![](/img/trans.png)
[英]What's the correct type for a variable in TypeScript that's initially undefined?
[英]what's correct: var declaration if undefined
在这种情况下,我听到过关于var
的用法的不同意见:
function(maybeUndefined) {
if(typeof maybeUndefined === 'undefined')
var maybeUndefined = 'bob';
}
有没有必要注意var
,或者没有,因为maybeUndefined
是function
的argument
?
在这种情况下,您不需要var
,因为mayBeUndefined
已经在函数范围内分配(提示:函数定义中的列出参数变量会导致这些变量在本地声明)。 因此, var
是完全可选的,尽管完全没有意义(并且可读性消耗殆尽)。
例:
function func ( arg1, arg2 ) {
var local1, local2;
function nested1 () {}
function nested2 () {}
// other code
}
这里我们有一个函数声明。 将此声明解析为函数对象时,将使用以下绑定为该函数创建词法环境(= scope):
(注意还有两个特殊的内置绑定: this
和arguments
。它们总是为所有函数对象创建。)
这些名称定义为本地绑定。 (此过程在“声明绑定实例化”中指定。警告:此算法不应由人类读取:-)
)因此,当名称被定义为参数时,不必将其声明为局部变量。 此机制与调用函数时是否为该参数传递值(参数)无关。
所以,即使你调用这样的函数:
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.