在这样的情况下,我听到了关于var
用法的不同意见:
function(maybeUndefined) {
if(typeof maybeUndefined === 'undefined')
var maybeUndefined = 'bob';
}
是否有必要注明var
,因为maybeUndefined
是argument
的{{1}}?
答案 0 :(得分:10)
在这种情况下,您不需要var
,因为mayBeUndefined
已经在函数范围内分配(提示:函数定义中的列出参数变量会导致这些变量在本地声明) 。因此,var
完全是可选的,尽管完全没有意义(并且可读性消耗殆尽)。
答案 1 :(得分:6)
示例:
function func ( arg1, arg2 ) {
var local1, local2;
function nested1 () {}
function nested2 () {}
// other code
}
这里我们有一个函数声明。将此声明解析为函数对象时,将使用以下绑定为该函数创建词法环境(= scope):
(请注意,还有两个特殊的内置绑定:this
和arguments
。这些绑定总是为所有函数对象创建。)
这些名称被定义为本地绑定。 (此过程在"Declaration binding instantiation"中指定。警告:此算法不应由人类:-)
读取。因此,当名称被定义为参数时,没有必要将其声明为局部变量。此机制与调用函数时是否为该参数传递值(参数)无关。
所以,即使你像这样调用函数:
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
}());
答案 2 :(得分:3)
你不应该再次使用var
,这对于可读性是不利的,并且变量将因为作为参数而在本地范围内。
另外,您应该注意它不是this
的一部分。如果使用this
关键字,new
只会限定为函数对象,并且由于您没有命名函数,在这种情况下似乎不太可能。如果没有new,this
引用窗口(如果使用undefined
则为use strict;
),其变量绝对不是参数具有局部范围的结果。
答案 3 :(得分:1)
<强>接口强>
包含函数参数实际上与作用变量的范围相同(换句话说,它与使用 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
;在函数 body 执行其中的代码之前,对象不会被“定义”;要使用伪代码可视化,它看起来像这样:
// 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()
}
功能调用
因此,当您调用某个函数时,它会“实现”或“执行”其 body (其“对象”)。当它这样做时,如果已经定义了推入 arguments
对象的对象,则该函数可以引用它们。如果不是,则抛出引用错误,记录该范围内的变量undefined
。
简而言之:
没有必要使用 var
来连接功能范围级变量(也称为“私有成员”),因为该语言已将arguments
对象附加到所有function
身体对象。
更多阅读:
JavaScript Memoization:“函数缓存”多个参数以获得更好的性能: http://decodize.com/javascript/javascript-memoization-caching-results-for-better-performance/