为什么在 IIFE 中使用赋值运算符时'this'指向'window' OBJ?



我想知道为什么示例会返回"全局"而不是"obj2"?"(obj2.say = obj1.say((("和"(obj2.say((("之间有什么区别? 这是代码:

var text = 'global';
var obj1 = { text: 'obj1', say: function () {console.log(this.text)}};
var obj2 = { text: 'obj2'};
(obj2.say = obj1.say)();

赋值的结果是分配的值。例:

var foo, bar;
foo = (bar = 42);
console.log(foo); // 42

因此,当你执行(obj2.say = obj1.say)时,赋值的结果是由分组运算符返回的,是obj1.say中的函数对象

整个表达式等效

var result = obj2.say = obj1.say;
result();

当一个函数被称为"正常"方式(func()(时,this指的是全局对象或undefined在严格模式下。


(obj2.say)()其实很特别。分组运算符本身不会解析对值的(内部(引用。即,obj2.say的结果在内部是一个引用,用于描述成员访问sayobj2。分组运算符(...)返回该引用不变,而不是将其解析为实际的函数对象。这就是为什么this会正确指向obj2.省略分组运算符具有相同的效果。

这实际上是在规范中提到的:

此算法不适用于GetValue计算表达式的结果。这样做的主要动机是,可以将deletetypeof等运算符应用于括号表达式。

因为 (obj2.say = obj1.say( 的值是一个普通的函数对象,而 obj2.say(( 是使用 obj2 的方法调用。

(obj2.say)()只会从obj2调用say函数。

(obj2.say = obj1.say)()会将obj1.say分配给obj2.say,然后调用它。

我不确定this.text- 我希望有人可以帮助解决这个问题 - 即使我很想知道。

最新更新