var obj = {
foo: function(){
console.log(this)
}
}
var bar = obj.foo
obj.foo() // 打印出的 this 是 obj
bar() // 打印出的 this 是 window
我很疑惑,直到找到大佬的解释:
ES5里有第三种函数调用的方式:
func(p1, p2)
obj.child.method(p1, p2)
func.call(context, p1, p2) // 先不讲 apply
初学者常用的是前两种,但其实第三种才是正常的调用形式,前两种是语法糖,都是可以转化成第三种的
func(p1, p2) 等价于
func.call(undefined, p1, p2)
obj.child.method(p1, p2) 等价于
obj.child.method.call(obj.child, p1, p2)
比如:
function func(){
console.log(this)
}
func()
转化为:
func.call(undefined) // 可以简写为 func.call()
按理说打印出来的 this 应该就是 undefined 了吧,但是浏览器里有一条规则:
如果你传的 context 是 null 或 undefined,那么 window 对象就是默认的 context(严格模式下默认 context 是 undefined)
因此上面的打印结果是 window。
那么一开始的代码就可以理解了,obj.foo() 就相当于obj.child.method(p1, p2) ,可以转化成obj.child.method.call(obj.child, p1, p2),此处即obj.foo.call(obj)