全面解析this
2021-03-23 本文已影响0人
沉默紀哖呮肯伱酔
每个函数的this实在调用时被绑定的,完全取决于函数的调用位置。我们找到函数的调用位置,然后运用以下四种绑定规则来判断函数的this指向。
1、默认绑定
function foo (){
console.log(this.a)
}
let a = 1
foo() // 1
函数的this会默认绑定到全局对象window上,如果在严格模式中,this绑定到undefined
2、隐式绑定
调用位置是否有上下文对象,或者被某个对象拥有或包含。
function foo(){
console.log(this.a)
}
let obj = {
a: 2,
foo:foo
}
let a = 1
obj.foo(); //2
function foo(){
console.log(this.a)
}
let obj1 = {
a: 2,
foo: foo
}
let obj2 = {
a: 3,
obj1: obj1
}
let a = 1
obj2.obj1.foo(); //2
3、显示绑定
function foo(){
console.log(this.a)
}
let obj = {
a: 1
}
foo.call(obj)
4、new绑定
function foo(a){
this.a = a
}
let bar = new foo(2)
console.log(bar.a) // 2
理解以上四种绑定规则以后,我们再来看一下四种绑定规则的优先级,哪个优先级高this绑定的就是哪个。
优先级
默认绑定的优先级是最低的
1、显示绑定 pk 隐式绑定
function foo(){
console.log(this.a)
}
let obj1 = {
a: 1,
foo: foo
}
let obj2 = {
a:2
}
console.log(obj1.foo()) // 1
obj1.foo.call(obj2) // 2
通过以上代码我们可以看到显示绑定的优先级高于隐式绑定
显示绑定 pk new 绑定
function foo(a){
this.a = a
}
let obj1 = {
foo
}
let bar = foo.bind(obj1)
bar(2)
console.log(obj1.a) // 2
let bar2 = new bar(3)
console.log(obj1.a) // 2
console.log(bar2.a) // 3
new修改了显示绑定 调用bar中的this,所以new绑定的优先级高于显示绑定
结论
我们判断一个函数的this指向,可以按照下面的顺序来判断
1、函数是否在new中调用,如果是的话 this绑定的是新创建的对象
let bar = new foo()
2、函数是否通过call、apply、bind的方式调用,如果是的话 this绑定的是指定的对象
let obj1 = {}
let bar = foo.call(obj1)
3、函数是否在某个上下文中被调用,如果是的话 this绑定的是函数调用的上下文
function foo(){
}
let obj1 = {
foo
}
let bar = obj1.foo()
4、除此之外 this绑定的就是全局对象 在严格模式下绑定的是undefined