JS中this的情况,apply,call和bind的理解


自己记录的笔记,仅作为自己的学习使用,如有错误请大家多多指出,谢谢大家。

1.this的情况

解析器在调用函数每次都会向函数内部传递一个隐含的参数 这个隐含的参数就是this,this指向的是一个对象 这个对象我们成为函数执行的上下文对象.关于执行上下文可以看之前我发的文章

this的情况:根据函数的调用方式不同,this会指向不同的对象

  1. 当以函数的形式调用时,this是window
  2. 当以方法的形式调用时,谁调用方法this就是谁(方法是函数作为某个对象的属性时,称之为方法,this就是指的这个对象)
  3. 当以构造函数的形式调用时,this就是新创建的那个对象

2.apply call 和 bind

有时候我们需要修改this的指向,指向我们需要的地方。
apply call和bind的作用就是动态的修改当前函数内部环境对象this的指向。
也就是通过这三个函数,可以使用属于另一个对象的方法,改变了this指向,可以用另一个对象中声明的方法。

2.1. call

2.1.1使用方法

定义一个person对象:包含三个参数

var person = {
  firstName:"Bill",
  lastName: "Gates",
  fullName: function () {
      return this.firstName + " " + this.lastName;
  }
}
console.log(person.fullName()); //Bill Gates 此时this指向对象person

新创建一个对象person1

//新创建一个对象
const person1 = {
  firstName : 'Steve',
  lastName  : 'Jobs'
}
//call 使用call函数 临时改变person中fullName函数的this指向 为对象person1
//此时对象person1就可以调用fullName方法
console.log(person.fullName.call(person1))//结果: Steve Jobs

同时也可以使用带参数的call方法

//同时也可以使用带参数的call方法
var person = {
  fullName: function (city, country) {
  		//注意这里的参数city和country不需要加this 如果加this 输出则为undefined 
  		//因为person1对象中 没有定义这两属性
      return this.firstName + " " + this.lastName +" " + city + " " + country;
  }
}

const person2 = {
  firstName : 'Steve',
  lastName  : 'Jobs'
}
//同时也可以传入参数
console.log(person.fullName.call(person2, 'Liu', 'Xing'));//结果Steve Jobs Liu Xing

2.2 apply

2.2.1使用方法

apply()方法与call方法很类似,作用一样,使用方法也类似
不同之处就是:
接收参数的方式不同
call()方法的参数传递,是一个一个传递的,分别接收参数
但是apply()接收参数的方法是数组形式的参数。
如果要使用数组而不是参数列表,则使用apply()方法更方便。
继续使用上一个例子:

//在person1上调用person的方法
console.log(person.fullName.apply(person1, ['Liu', 'Xing']));//Steve Jobs Liu Xing

2.2.2应用场景

函数之间的相互调用。
例如使用Math.max()方法找到数组的最大数:

console.log(Math.max(1,2,3));//3

//js中数组没有max方法 所以可以使用apply方法 这样数组就调用了max方法
Math.max.apply(null,[1,2,3]) // 3  null的时候 this指向还是全局对象 也可以是" "
Math.max.apply(person1,[1,2,3]) //3

JavaScript 严格模式
在 JavaScript 严格模式下,如果 apply() 方法的第一个参数不是对象,则它将成为被调用函数的所有者(对象)。在“非严格”模式下,它成为全局对象。

2.3 bind

bind是永久修改函数this指向,但是它修改的不是原来的函数;而是返回一个修改过后新的函数,此函数的this永远被改变了,绑定了就修改不了。且传入参数的方式与call()方法一样,只能一个一个的传入。

2.3.1使用方法

let newFn = person.fullName.bind(person1,'Liu', 'Xing');//Steve Jobs Liu Xing
console.log(newFn())//此时newFn方法this指向就是person1

三者的区别

  • 执行方式不同

    call和apply是改变后页面加载之后就立即执行,是同步代码

    bind是异步代码,改变之后不会立即执行,而是返回一个新的函数

  • 传参方式不同

    call和bind是一个一个传入,不能使用剩余参数的方式

    apply可以使用数组的方式传入的,只要是数组方式就可以将剩余参数传入
    例子:

  • 修改this的性质不同

    call、apply只是临时的修改一次,也就是call和apply方法的那一次;当再次调用原函数的时候,它的指向还是原来的指向。

    bind是永久修改函数this指向,但是它修改的不是原来的函数;而是返回一个修改过后新的函数,此函数的this永远被改变了,绑定了就修改不了。

    3.参考文献

    1.W3School讲解
    2.Summer_dog的博客 讲解的很清楚,大家可以去看https://blog.csdn.net/qq_43000315/article/details/125360096

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值