全面解析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

上一篇下一篇

猜你喜欢

热点阅读