ZhangYang's Blog

JavaScript的this值

this面试题

1
2
3
4
5
6
7
8
9
var obj = {
foo: function(){
console.log(this)
}
}
var bar = obj.foo
obj.foo() // 打印出的 this 是 obj
bar() // 打印出的 this 是 window

函数调用

JS(ES5)里面有三种函数调用形式

1
2
3
func(p1, p2)
obj.func(p1, p2)
func.call(context, p1, p2)

第三种调用形式,才是正常调用形式

1
func.call(context, p1, p2)

其他两种等价地变为 call 形式

1
2
3
4
5
func(p1, p2) 等价于
func.call(undefined, p1, p2)
obj.func(p1, p2) 等价于
obj.func.call(obj, p1, p2)

this一个函数时传的context

实例一

传的 context 就 null 或者 undefined,那么 window 对象就是默认的 context,打印结果是window

1
2
3
4
5
6
7
8
9
10
function func(){
console.log(this)
}
func()
// 等价于
function func(){
console.log(this)
}
func.call(undefined) // 可以简写为 func.call()

希望这里的 this 不是 window,修改为

1
func.call(obj) // 那么里面的 this 就是 obj 对象了

实例二

this 就是 obj

1
2
3
4
5
6
7
8
9
var obj = {
foo: function(){
console.log(this)
}
}
obj.foo()
// 按照「转换代码」,我们将 obj.foo() 转换为
obj.foo.call(obj)

面试题答案

1
2
3
4
5
6
7
8
9
10
11
12
13
var obj = {
foo: function(){
console.log(this)
}
}
var bar = obj.foo
obj.foo() // 转换为 obj.foo.call(obj),this 就是 obj
bar()
// 转换为 bar.call()
// 由于没有传 context
// 所以 this 就是 undefined
// 最后浏览器给你一个默认的 this —— window 对象

总结

  • this 就是你 call 一个函数时,传入的第一个参数
  • 如果你的函数调用形式不是 call 形式,请按照「转换代码」将其转换为 call 形式