繁体   English   中英

什么是正确的:var声明,如果未定义

[英]what's correct: var declaration if undefined

在这种情况下,我听到过关于var的用法的不同意见:

function(maybeUndefined) {
    if(typeof maybeUndefined === 'undefined')
        var maybeUndefined = 'bob';
}

有没有必要注意var ,或者没有,因为maybeUndefinedfunctionargument

在这种情况下,您不需要var ,因为mayBeUndefined已经在函数范围内分配(提示:函数定义中的列出参数变量会导致这些变量在本地声明)。 因此, var是完全可选的,尽管完全没有意义(并且可读性消耗殆尽)。

例:

function func ( arg1, arg2 ) {
    var local1, local2;

    function nested1 () {}
    function nested2 () {}

    // other code
}

这里我们有一个函数声明。 将此声明解析为函数对象时,将使用以下绑定为该函数创建词法环境(= scope):

  • ARG1
  • ARG2
  • LOCAL1
  • local2
  • nested1
  • nested2
  • 这个
  • 参数

(注意还有两个特殊的内置绑定: thisarguments 。它们总是为所有函数对象创建。)

这些名称定义为本地绑定。 (此过程在“声明绑定实例化”中指定。警告:此算法不应由人类读取:-) )因此,当名称被定义为参数时,不必将其声明为局部变量。 此机制与调用函数时是否为该参数传递值(参数)无关。

所以,即使你调用这样的函数:

func(123);

名称arg2仍将被定义(作为函数环境中的绑定),尽管其值最初将针对该特定调用undefined

顺便说一句,如果你使用严格的语言 (推荐!),函数环境是静态的 ,这意味着上述绑定被保证是函数环境中唯一的绑定。 另一方面, 默认语言提供了某些机制, 动态地添加/删除函数环境中的绑定。 例:

(function () {

    // the name "temp" does not exist as a binding in the function's environment

    eval('var temp');

    // now it does

    delete temp;

    // and it's gone again

}());

你不应该再次使用var ,这对于可读性是不利的,并且变量将因为作为参数而在本地作用域。

另外,你要注意,它不是一部分this 如果使用了new关键字,那么this只会限制在函数对象中,并且由于您没有命名函数,在这种情况下似乎不太可能。 如果没有new, this引用window(或者如果use strict;则使用undefined ),其变量肯定不是具有局部范围的参数的结果。

界面

包含函数参数实际上与作用域变量相同(换句话说,它实际上与使用var关键字定义函数级引用相同)。 提供函数参数(在JavaScript中)的主要原因是您自己的接口首选项。

arguments对象

参数仍然可以传递给没有参数的函数,并且仍然可以在'hidden' arguments对象中访问 - 它是一种“伪数组”(如果你愿意的话),因为它在功能上是一个数组,但是没有配备相同的API JavaScript为Array (伪类型)配备:

// The following functions do the same thing, but one is "more readable"

function foo() {
  return arguments;
}

function bar(baz, qux) {
  return arguments;
}

评估(界面)与执行(实施)

评估两个函数时(在文件'load'上), arguments对象在每个函数定义中都是undefined ; 在函数执行其中的代码之前,对象不会被“定义”; 使用伪代码可视化 ,它看起来像这样:

// Function bodies (as objects)
foo : {
  arguments : new Array // [undefined]
  __proto__ : Empty() // the super-object that allows this object to inherit "functionality"
}

bar : {
  arguments : new Array(baz, qux) // [undefined, undefined]
  __proto__ : Empty()
}

函数调用

所以当你调用一个函数时,它“实现”或“执行”它的主体 (它的“对象”)。 当它这样做时,如果已经定义了推入arguments对象的对象,那么该函数可以引用它们。 如果不是,则抛出引用错误,记录该范围内的变量undefined

简而言之:

没有必要使用var来连接函数范围级变量(也称为“私有成员”),因为该语言已经将arguments对象附加到所有function体对象。

更多阅读:

JavaScript Memoization:“函数缓存”多个参数以获得更好的性能: http ://decodize.com/javascript/javascript-memoization-caching-results-for-better-performance/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM