为何this值存在差异?两种函数调用方式的区别探究
为什么
(p.foo = o.foo)()和p.foo();的this指向不同? 先回顾你给出的代码示例:
function foo() { console.log( this.a ); } var a = 2; var o = { a: 3, foo: foo }; var p = { a: 4 }; // 输出3 o.foo(); // 输出2 (p.foo = o.foo)(); // 输出4 p.foo = o.foo; p.foo();
咱们一步步拆解两种场景的差异:
1. 先赋值再调用:p.foo = o.foo; p.foo();
当执行p.foo = o.foo时,你把o上的foo函数引用赋值给了p的foo属性。这时候p对象拥有了自己的foo方法,指向原foo函数。
接下来调用p.foo()时,函数是作为p的方法被调用的——这种情况下,JavaScript会自动把this绑定到调用该方法的对象(也就是p),所以this.a就是p.a,自然输出4。
2. 赋值后立即调用:(p.foo = o.foo)()
这里的关键是理解赋值表达式的返回值:p.foo = o.foo这个操作的结果,并不是p.foo这个绑定到对象的方法,而是被赋值的那个值本身——也就是原foo函数的独立引用。
换句话说,(p.foo = o.foo)执行完后,返回的是和foo变量直接指向同一个函数的引用,而不是和p.foo绑定的方法。当你在后面加()调用它时,相当于直接调用了这个函数(没有任何对象作为调用上下文)。
在非严格模式下,这种“裸调用”的函数,this会默认绑定到全局对象。而你全局作用域里的a是2,所以this.a就是2,输出自然是2。
简单总结:
p.foo()是对象方法调用,this指向p(p.foo = o.foo)()是独立函数调用,this指向全局对象(非严格模式下)
内容的提问来源于stack exchange,提问作者Alexey Tseitlin
相关产品推荐
相关产品推荐

