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

why 'this' point to 'window' obj when using assignment operator in iife?

我想知道为什么这个例子会 return 'global' 而不是 '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)();

(obj2.say)() 只会从 obj2.

调用 say 函数

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

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

因为 (obj2.say = obj1.say) 的值是一个普通的 Function 对象,而 obj2.say() 是对 obj2.

的方法调用

赋值的结果是赋值的值。示例:

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

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

整个表达式等价于

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

并且当一个函数被调用时 "normal" 方式 (func()), this refers to the global object or is undefined in strict mode.


(obj2.say)()其实挺特别的。单独的分组运算符不会 解析 (内部)对值的引用。 IE。 obj2.say 的结果在内部是描述成员访问 sayobj2 的引用。分组运算符 (...) returns 引用未更改,未将其解析为实际函数对象。这就是 this 会正确指向 obj2 的原因。省略分组运算符具有相同的效果。

这实际上是called out in the spec:

This algorithm does not apply GetValue to the result of evaluating Expression. The principal motivation for this is so that operators such as delete and typeof may be applied to parenthesized expressions.