为什么我可以在对象文字中对同一个变量的赋值中使用变量,但它会在函数文字中创建自引用?

时间:2017-03-07 21:35:25

标签: javascript

为什么我可以像这样回收对象文字中的变量:

var x=1;
x={
a:x;
}
console.log(x.a);//1

但不在函数文字

var y=2;
y=()=>y;
console.log(y()); //y() //?? why not 2?
console.log(y()()()()()()); //y()

x的情况适用于x最初是否是原始的。 y情况似乎与箭头函数或标准函数相同。

我正在使用x case没有问题的方法,该方法将对象作为参数或字符串(然后将其转换为对象)。我有一个类似的函数情况(如果y是一个字符串,使它成为一个返回该字符串的函数),但它的工作方式不同。

我知道我可以使用像

这样的东西
var y=2;
let val=y;
y=()=>val;
console.log(y());//2

但我不知道为什么这是必要的。

2 个答案:

答案 0 :(得分:2)

当评估变量时,就是

当你这样做时

x={
a:x;
}

然后在那一刻读取x的当前值,分配给属性a,最后将新对象分配给x

即。 x的评估在新值分配给x之前发生

y=()=>y;

函数内部的变量(y)在调用函数之前不会被计算,这会在稍后发生。

即。 y的评估在新值分配给y后发生

您要覆盖现有变量这一事实使得这更难以理解。让我们看一个更简单的例子:

var x = 42;
var obj = {a: x};
x = 21;
// logs 42 because that was the value of `x` at the moment the object was created
console.log(obj.a);


var y = 42;
var f = () => y;
y = 21;
// logs 21 because at the moment the function is called, the value of `y` has already 
// been updated
console.log(f()); 

答案 1 :(得分:1)

为了增加一个已经很好的答案,可以使用一个闭包来使它工作"通过将y的当前值存储在分配给y的函数的作用域链中:

y = (x=>()=>x)(y);

简而言之,使用(x=>()=>x)调用y首先将参数值x设置为y,然后返回一个返回x值的嵌套函数在其外部范围内。

异步代码中通常使用更复杂的闭包来引用和更新在创建嵌套函数时在外部函数中定义的变量和参数的值。