javascript 中this 的理解以及call、apply、bind 函数用法

javascript 中this 的理解以及call、apply、bind 函数用法

注意:下面的js代码并未嵌入html后的运行结果,而是直接通过node执行js脚本运行代码得到的结果,(两种运行方式得到结果有所不同)

目录

  • javascript 中this 的理解以及call、apply、bind 函数用法
    • this的指向性问题
    • 那么**this**的指向可以发生改变吗?怎么改变它?
    • 使用 call、apply、bind 函数
  • 总结

this的指向性问题

首先通过一个案例引入this的指向性问题

案例一

var name = "小王" ,age = 17;

var obj = {
  name : "小李",
  objAge: age,   // 
  myFun(){   // 等价于 myFun:function myFun....这种写法
    console.log(this.name +  '年龄' + this.age);
  }
}

console.log(obj.objAge)
obj.myFun()

//结果
//17
//小李年龄undefined

通过分析输出的结果,其中的obj.myFun()执行的时候输出"小李年龄undefined",也就是说 obj.myFun()函数中的this也就是obj这个实例对象,为证明这个说法我们修改上述的代码。
案例二

var name = "小王" ,age = 17;

var obj = {
  name : "小李",
  objAge: age,
  myFun(){
    console.log(this === obj)
    console.log(this)
  }
}
obj.myFun()
//结果
// true
// { name: '小李', objAge: 17, myFun: [Function: myFun] }

通过修改后的代码,通过输出结果可以发现,obj.myFun()这个函数中所指的this就是obj这个对象。

注意上述myFun都是通过function的方式去声明数组的,若是箭头函数this的指向则会不同,
下面通过案例来展示箭头函数中this指向的不同


我们直接上代码看具体的案例

案例三

var name = "小王" ,age = 17;

var obj = {
  name : "小李",
  objAge: age,
  myFun:() => {
    console.log(this)
  }
}

obj.myFun()

//运行结果
// {}

可以看到这个案例中,只是将obj中原来的myFun这个函数的声明从function改成了用箭头函数的声明方式,但是this 的指向却从原来指向的obj这个实例对象变成了**{}** 这个空对象(通过嵌入html代码中运行的话输出的windows这个对象),这是因为箭头函数中的this会找到找到当前对象的上一层,同样的我们通过一个案例证明。

案例四

var obj2 = {
  name: "小池",
  myFun(){
    const test = () => {
      console.log(this)
      console.log(this === obj2);
    }
    test();
  }
}

obj2.myFun()

// 运行结果
// { name: '小池', myFun: [Function: myFun] }
// true

可以看到我们在myFun这个函数中声明了一个箭头函数,由于test函数是通过箭头函数声明的,其内部的this会向外找一层也就是myFun这个函数所对应的this结合输出结果与上述的案例二中的结果相符合。


那么this的指向可以发生改变吗?怎么改变它?

案例五

//修改上面的案例一的代码
var name = "小王" ,age = 17;

var obj = {
  name : "小李",
  objAge: age,
  myFun(){
    console.log(this.name + "年龄" + this.age)
  }
}

var obj2 = {
  name: "小池",
  age,
}

obj2.myFun = obj.myFun
obj.myFun()
obj2.myFun()

// 运行结果
// 小李年龄undefined
// 小池年龄17

可以看到通过obj2访问到的myFun中的this又指向了obj2obj2.myFun = obj.myFun
可以理解成在obj2上写了一份myFun函数

使用 call、apply、bind 函数

案例六 不传参

var name = "小王" ,age = 17;

var obj = {
  name : "小李",
  objAge: age,
  myFun(){
    console.log(this.name + "年龄" + this.age)
  }
}

var db = {
  name: "德玛",
  age: 99,
}
obj.myFun.call(db);
obj.myFun.apply(db);
obj.myFun.bind(db)();
// 结果
// 德玛年龄99
// 德玛年龄99
// 德玛年龄99

可以看到在这个案例中,call 、apply、bind函数都将obj.myFun函数中的this指向为db
而此时这三个函数的用法几乎相同,call、apply函数可以直接帮你修改其中的this指向并且同时调用,而bind在修改this的指向后返回的是一个函数。

案例七 传参

var name = "小王" ,age = 17;

var obj = {
  name : "小李",
  objAge: age,
  myFun(mom, fat){
    console.log(mom + "--" + fat)
  }
}

var db = {
  name: "德玛",
  age: 99,
}
obj.myFun.call(db,"A","B");
obj.myFun.apply(db,["A","B"]);
obj.myFun.bind(db,"A","B")();
obj.myFun.bind(db,["A","B"])();

// 运行结果
// A--B
// A--B
// A--B
// A,B--undefined

可以看到三个函数的传参方式有所不同

  • call 函数,多个参数间直接用","隔开
  • apply函数,多个参数通过数组的形式传入
  • bind函数,多个参数直接用","隔开

总结

理解js中this 的指向还是很重要的,不然有时候会遇到一些坑,不如react中的用类写组件的方式就容易遇到这样的问题。

你可能感兴趣的:(javascript)