Javascript 在闭包中到底是如何进行绑定的?

Javascript 在闭包中到底是如何进行绑定的?,javascript,closures,symbol-table,name-binding,Javascript,Closures,Symbol Table,Name Binding,首先,您可以关闭尚未定义的变量(s)。如果使用词汇(静态)作用域,这怎么可能呢 其次,删除原始的s后,f()可以找到新的s。这是否意味着闭包绑定到变量名,而不是引用、符号表索引或更高的机器级别?由于原始的s被删除,我希望e词法作用域闭包会抛出一个错误。新的s仅重用名称,与原始的s无关 第三,匿名函数作用域中的s没有被f()使用,这是否意味着词法作用域确实在起作用?这个例子相当于 function f() { return s; } // works fine though no `s` is d

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

其次,删除原始的
s
后,
f()
可以找到新的
s
。这是否意味着闭包绑定到变量名,而不是引用、符号表索引或更高的机器级别?由于原始的
s
被删除,我希望e词法作用域闭包会抛出一个错误。新的
s
仅重用名称,与原始的
s
无关


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

这个例子相当于

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 (?)
})();
Javascript变量声明被提升到其作用域的顶部,然后被声明。然后在用户设置它们的位置定义它们。因此,您可以在函数范围中声明javascript变量之前引用它

还要注意,delete通常用于对象的属性,而不是用var声明的对象。在这种情况下,delete不起作用,不管闭包是什么。请看这里的小提琴:

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

提及

第二,删除原始s后,f()可以找到新的s。做 这意味着闭包绑定到变量名而不是引用 或符号表索引或更高的机器级别?我会的 期望从e词法作用域闭包抛出一个错误,因为 原稿已删除。新的s只是重复使用了这个名称,没有任何内容 和原来的s有关

没有新的声明,所有声明都已悬挂。最后只有一个s。 吊装仍然适用

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


是的,匿名函数中的s是局部的,在这种情况下,闭包是在全局s上形成的。

我想我们可以用“提升”来回答任何“闭包”问题,甚至不用阅读它们。您可能会发现尝试两种变体很有启发性:首先,将代码放在IIFE-
(function(){…code…})中。然后,尝试您的原始代码,除了使用语句
“use strict”(就是那个字符串常量)在最顶端。(实际上,
“使用严格”
修改可能是最有趣的。)无论如何,是的,这都是关于词法作用域的。oops实际上在严格模式下,
删除
语句根本不起作用。我认为“第二个”实际上是由于
delete s
没有任何影响,而不是如中所示的吊装
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 (?)
})();