为什么在函数调用中"()"更改"this"



谈话很便宜;放码过来。

// equals to this.test = "inside window"
var test = "inside window";
function f () {
console.log(this.test)
};
var obj = {
test: "inside object",
fn: f
};
obj.fn();      // "inside object"   --> fine
(obj).fn();    // "inside object"   --> fine
(1, obj).fn(); // "inside object"   --> fine
(obj.fn)();    // "inside object"   --> fine
(0 || obj.fn)(); // "inside window"   --> why?
// reference equality check
console.log(
f === obj.fn && 
(obj.fn) === f && 
f === (1, obj.fn)
); // all equal :/

我读过ydkjs的书,熟悉调用站点和动态this绑定,但我不明白为什么最后一个函数调用的this上下文是window;在这个受控实验中()comma operator发生了变化,正如您在最后一条语句中看到的,comma operator正在做一些奇怪的事情。我怀疑它在返回值时执行赋值(因为如果我们执行赋值,会发生相同的结果(,但我不确定。

更新:

&&||算子(0 || obj.fn)()也有影响

给定:

foo.bar()

bar内部,this将是foo

(也有例外,例如bar是用箭头函数定义的,但在这种情况下不适用(。

给定:

const bar = foo.bar;
bar();

现在,函数在没有foo上下文的情况下被调用,因此this现在是默认对象(在浏览器中是window(。

表达式(1, foo.bar)的计算结果为右侧。这就是函数。

就像你把它复制到一个变量中一样,这会在你调用它之前断开函数与对象的连接,所以你会得到同样的效果。

没有赋值,因为您没有涉及变量,但您调用的是表达式的结果,而不是直接调用对象方法。

为了支持@Quentin的答案,逗号运算符确实将最后一个操作数作为没有上下文的函数返回(因此是窗口(,而不是对象蓝图中的操作数。

只有在通过带有对象的函数调用apply/call时,它才能获取上下文。

(1, a.fn).call(a);  // "inside object"
(1, a.fn).apply(a); // "inside object"

相关内容

  • 没有找到相关文章

最新更新