首先声明,this是在运行时绑定的,并不是在编写时绑定,它的上下文取决于函数调用时的各种条件。常见的this绑定规则有四种,如下:
1.默认绑定
当函数被独立调用时,this默认绑定到全局window对象上
function foo(){
console.log(this.a)
}
var a = 1
foo() // 输出1
- 隐式绑定
取决于调用的时候是否被某个对象所引用
function foo(){
console.log(this.a)
}
var obj = {
a:1,
foo: foo
}
obj.foo() // 输出1
存在一种情况,this会丢失,比如:
function foo(){
console.log(this.a)
}
var obj = {
a:1,
foo: foo
}
var bar = obj.foo;
var a = 2
bar() // 输出2
3.运用call(),apply()或es5的bind() 来显示绑定
function foo(){
console.log(this.a)
}
var obj = {
a:1
}
foo.call(obj) // 输出1
记住,bind()返回的是一个硬绑定的新函数,它会把你指定的参数设置为this的上下文。
4.new绑定
当我们使用new来调用构造函数时,javascript会先创建一个新对象,然后把它绑定到构造函数的this上。
5.箭头函数
以上的四种规则不适用在箭头函数中,箭头函数的this是根据函数定义时外层作用域来决定的。
function foo(){
return (a) => {
//this继承了外层foo的作用域
console.log(this.a)
}
}
var obj1 = { a:1}
var obj2 = {a:2}
var bar = foo.call(obj1)
bar.call(obj2) // 输出1
//在箭头函数出来之前,我们使用这种方式定义的
function foo(){
var self = this
setTimeout(function(){
console.log(self.a)
},100)
}
var obj = { a:1}
foo.call(obj) // 输出1