我在互联网上通过了这个有趣的测验。
console.log((function(x, f = (() => x)){
var x;
var y = x;
x = 2;
return [x, y, f()]
})(1))
Run Code Online (Sandbox Code Playgroud)
选择是:
[2,1,1]
[2,未定义,1]
[2,1,2]
[2,未定义,2]
我选择了解决方案2 TBH,基于x已被重新定义,y被声明和定义为没有值的情况,并且f具有不同的作用域,因此获得的全局x内存点比函数x内存点大。
但是,我在jsbin.com中尝试过
我发现这是解决方案1,虽然不确定为什么会弄乱函数主体并var x从函数主体中删除,但发现响应更改为#3,这在x值更改时是有意义的,因此表明x和f为2,y为1,这是全局声明的。
但我仍然不明白为什么它显示1而不是未定义。
T.J*_*der 24
但我仍然不明白为什么它显示1而不是未定义。
不只是你 这是规范的深层部分。:-)
关键是两个x。对真的。有参数 x,有变量 x。
包含表达式的参数列表(如f的默认值)具有与函数主体的范围分开的自己的范围。但是在可能具有表达式的参数列表之前,在具有参数var x的函数内x没有任何效果(x仍然是具有参数值的参数)。因此,为了保留它,当其中有一个带有表达式的参数列表时,将创建一个单独的变量,并将参数的值复制到函数主体开头的变量中。这就是这种看似奇怪 (不只是看似)奇怪行为的原因。(如果您是那种喜欢介绍规范的人,则此复制是步骤28FunctionDeclarationInstantiation。)
由于f的默认值() => x在参数列表范围内创建,因此它引用的是参数 x,而不是var。
因此第一个解决方案[2, 1, 1]是正确的,因为:
2被分配给x函数主体中的var 。因此,在函数末尾,var x为2。1在获得值之前y从var 分配给,所以在函数末尾是。xx2y1x的值从来没有改变,因此f()导致1在该函数结束这是因为,虽然代码是这样写的,而不是(我已经删除不必要的括号并添加缺少的分号):
console.log(function(param_x, f = () => param_x) {
var var_x = param_x;
var y = var_x;
var_x = 2;
return [var_x, y, f()];
}(1));Run Code Online (Sandbox Code Playgroud)
...我从函数主体中删除了var x,发现响应更改为#3 ...
#3是[2, 1, 2]。是正确的,因为当您var x从函数中删除时,只有一个x参数(从参数列表中的函数主体继承)。因此,分配2给会x更改参数的值,然后f返回。
服用earier例如用param_x和var_x,这里是什么样子,如果你删除喜欢var x;的吧:
console.log(function(param_x, f = () => param_x) {
var y = param_x;
param_x = 2;
return [param_x, y, f()];
}(1));Run Code Online (Sandbox Code Playgroud)
这是原始代码的带注释的说明(删除了多余的括号并添加了缺少的分号):
// /---- the parameter "x"
// v vvvvvvvvvvv--- the parameter "f" with a default value
console.log(function(x, f = () => x) {
var x; // <=== the *variable* x, which gets its initial value from the
// parameter x
var y = x; // <=== sets y to 1 (x's current value)
x = 2; // <=== changes the *variable* x's value to 2
// +---------- 2, because this is the *variable* x
// | +------- 1, because this is the variable y
// | | +--- 1, because f is () => x, but that x is the *parameter* x,
// | | | whose value is still 1
// v v vvv
return [x, y, f()];
}(1));
Run Code Online (Sandbox Code Playgroud)
关于标题的最后说明:
在IIFE中两次声明变量
该变量仅声明一次。另一件事是参数,而不是变量。区别很少重要...这是那些罕见的时期之一。:-)
| 归档时间: |
|
| 查看次数: |
455 次 |
| 最近记录: |