4
function f() { return s; } // works fine though no `s` is defined yet !

var s=1;
f(); // 1

delete s;

var s=2;
f(); // 2 

(function() {
var s=3;
f(); // 2 and not 3 which means lexical scoping is at play (?)
})();

首先,您可以关闭s尚未定义的变量 ( )。如果使用词法(静态)作用域,这怎么可能?

第二,删除原来的sf()可以找到新的s。这是否意味着闭包绑定到变量名而不是引用或符号表索引或更机器级别的东西?我希望从 e 词法作用域闭包中抛出一个错误,因为原来s的被删除了。新的s只是重用了这个名字,和原来的没有任何关系s

第三,s匿名函数作用域内部不被 使用f(),这是否意味着词法作用域确实在起作用?

4

2 回答 2

3

首先,您可以关闭尚未定义的变量...如果使用词法(静态)范围,这怎么可能?

参考吊装

其次,删除原来的s后,f()可以找到新的s。这是否意味着闭包绑定到变量名而不是引用或符号表索引或更机器级别的东西?我希望 e 词法作用域闭包会引发错误,因为原始 s 已被删除。新的s只是重用了名字,和原来的s没有任何关系。

没有 new s,所有声明都被提升了。最后只有一个s。吊装仍然适用。

第三,匿名函数范围内的 s 不被 f() 使用,这是否意味着词法范围确实在起作用?

是的,匿名函数内部的 s 对它来说是本地的,在这种情况下,闭包是在全局 s 上形成的。

于 2013-03-29T15:00:35.953 回答
2

这个例子等价于

var s;
function f() { return s; } // works fine though no `s` is defined yet !

s=1;
f(); // 1

delete s;

s=2;
f(); // 2 

(function() {
var s=3;
f(); // 2 and not 3 which means lexical scoping is at play (?)
})();

Javascript 变量声明被提升到其范围的顶部,然后被声明。然后在用户设置它们的位置定义它们。因此,您可以在函数范围内声明它之前引用一个 javascript 变量。

另请注意,delete 通常用于对象的属性,而不是用 var 声明的对象。在这种情况下删除无效,无论是否关闭。在这里看小提琴:jsfiddle

于 2013-03-29T14:58:00.883 回答