再次搞懂this指向问题

138 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第2天,点击查看活动详情

首先this问题也是我一直不搞不太懂的一个难点,最近通过书籍+视频的方式重新学习了一下关于这方面的问题

this的绑定规则

默认绑定

独立的函数调用,就是函数没有被绑定到某个对象上,此时this指的是window

示例1.
var name = 'windowName'
function sayName(){
  var name = 'kobe'
  console.log(this.name)  //windowName
}

sayName()

示例2.
var name = 'windowName'
var p = {
  name:null,
  fn : function(){
        console.log(this.name)  //windowName
  }
}

var p1 = p.fn
p1

示例3.
var name = 'windowName'
function fn() {
  var name = 'kobe'
  inner()
  function inner() {
    console.log(this.name)  //windowName
  }
}

fn()

总结:函数独立调用的时候,this是指向window

隐式绑定

通过某个对象进行对函数的调用

示例1.
var obj = {
  name: "kobe",
  foo: function() {
    console.log(this.name)  //kobe
  }
}

obj.foo() // obj对象
示例2.
var obj = {
  name: "kobe",
  eating: function() {
    console.log(this.name + "在吃东西")
  },
  running: function() {
    console.log(obj.name + "在跑步")
  }
}

obj.eating()  //kobe在吃东西
obj.running()   //kobe在跑步

示例3.
var obj1 = {
  name: "obj1",
  foo: function() {
    console.log(this.name)  //obj2
  }
}

var obj2 = {
  name: "obj2",
  bar: obj1.foo
}

obj2.bar()

显示绑定

通过call,apply,bind改变this指向

function foo() {
  console.log(this.name)
}
var obj = {
  name: "obj"
}

// call/apply是可以指定this的绑定对象
foo.call(obj)

箭头函数

箭头函数没有自己的this,this由外层上下文决定

var name = "windowsName";
var a = {
    name: "Cherry",
    fn:() => {
      console.log(this.name)
    }
}

a.fn() //windowsName

上述代码可以看出箭头函数内部的this是外层上下文

构造函数

构造函数中的this指向创建的实例对象

function person() {
  this.name = "kobe";

}

let p = new person();
console.log(p.name) //kobe

面试题

obj = {
  func() {
    const arrowFunc = () => {
      console.log(this._name)
    }

    return arrowFunc
  },

  _name: "obj",
}

obj.func()()  //obj

func = obj.func  
func()()  //undefined

obj.func.bind({ _name: "newObj" })()() //newObj

obj.func.bind()()() //undefined

obj.func.bind({ _name: "bindObj" }).apply({ _name: "applyObj" })() // bindObj

被bind()永久绑定的this,即便用call,apply 也无法修改this的指向了