手把手教学,终于搞懂手写call&apply&bind!!!

319 阅读2分钟

赶紧学习拉开差距- 熊猫头学习表情- 表情包系列之家

准备测试素材🍅🍆🌽🌶🍄

两个对象,每个对象里面都有自己的this指向

我们可以通过call apply bind方法来测试实现:改变this指向到另一个对象

call

原本的👈

1.say方法里面的this从person改成了student

2.参数是散装的

3.立马执行

person.say.call(Student,19,'chengdu')  // Student 19 chengdu

自己实现的👉

如何实现:更改this的指向?

1.context.temp = this 首先搞懂this是什么?

这个this,其实就指向的是调用这个函数的对象

person.say.mycall(Student,19,'chengdu') 所以这个this 是 person.say 这个对象

所以后面我们context.temp(...validParamsArguments),其实这个函数对象的执行

2.context.temp = this 再梳理这个表达式

首先context就是我们传入的那个新的this指向 context = Student, 这里的Student是构造函数方法对象, 注意是对象

我们先在context(Student)上面创建一个临时值temp来存储this(this其实就是那个函数)

然后传入参数,执行this(执行函数)context.temp()==> Student.temp()

这里的temp() 是加载到函数对象Student中的, 不是加载到Student的构造函数中,

这里定义的function Student(){} 中的Student 是一个Function对象

function Student() {
    this.name = 'student'
    //this.temp = function(age,address){
    //	console.log(this.name, age, address)
    //}
}

Student.temp = function(age,address){
    console.log(this.name, age, address)
}

其实temp函数是被Student调用的,那么temp函数里面的this.name 的this就指向的是Student里面的this.name

最后删除这个临时temp

注意🚫🚫🚫:arguments
1.类数组转换

arguments是Arguments,是一个类数组 ,每个方法内部有点一个arguments变量, 表示方法传入的参数, 但是call接受的是一个正常的数组

所以需要将arguments转换成正常的数组

实现:const validAllArguments = [...arguments]

2.剔除arguments里面的第一个参数

因为arguments里面的第一个参数是我们要改变的this的那个指向,而不是真正的参数,所以我们要去掉

实现:const validParamsArguments = validAllArguments.slice(1)

注意⚠⚠⚠:const result = context.temp(...validParamsArguments) 为undefined

context.temp(...validParamsArguments)是没有返回值的,result是等于undefined的

但是因为call是立即执行,所以我们没必要取返回值return出去


apply

原来的👆

1.say方法里面的this从person改成了student

2.参数是数组

3.立马执行

person.say.apply(Student,[19,'chengdu'])  // Student 19 chengdu

自己实现的👇

关于参数的步骤解析

  1. const validAllArguments = [...arguments] 此时validAllArguments 就为 [studeng, 参数数组] ,因为我们参数传入的是一个数组嘛!
  2. const validParamsArguments = validAllArguments.slice(1) 此时validParamsArguments就为 [参数数组]
  3. validParamsArguments[0] 在validParamsArguments数组里面 取参数数组
  4. ...validParamsArguments[0] 并且将参数数组解构,最后传入的是散装的参数,因为那个函数接受的是要散装的参数

bind

原本的🤛

1.散装的参数

2.不会自动执行

 const bindFn = person.say.bind(Student,19,'chengdu')
 bindFn()

自己实现的🤜

核心代码:其实就是把它包起来

const resultFunc = function () {
    context.temp(...validParamsArguments)
}
return resultFunc

全部代码

能不能给我点个赞()——熊猫头求点赞系列- 表情包 ...