call、apply 和 bind

74 阅读2分钟

上述这三个方法使用对象都是函数,即只有函数可以调用这些方法

首先我们说明 this 指向

这三个方法所实现的功能是一样的 —— 修改 函数的 this 指向

倘若 我们定义一个 function 

function fun(){    console.log(this)}fun()

输出是 window 对象

函数是谁调用 那么 this 就指向谁,但是箭头函数的 上下文是父级的上下文,也就是说谁调用了父级,那么箭头函数的 this 就指向谁

let obj = {    name: '小猫',    say: function () {        console.log(this)        console.log('喵喵')    },    play: () => {        console.log(this)        console.log(this.name+'在玩')    },    eat: function (food1, food2) {        console.log(this.name + '吃' + food1 + '和' + food2)    }}obj.say()obj.play()

最终输出结果是

如果我们需要把这几个函数的 this 指向换一个对象 那么我们就需要借助 call apply 或者 bind

call 

当我们使用 call 时

let obj = {    name: '小猫',    say: function () {        console.log(this)        console.log('喵喵')    },    play: () => {        console.log(this)        console.log(this.name+'在玩')    },    eat: function (food1, food2) {        console.log(this.name + '吃' + food1 + '和' + food2)    }}let dog={    name:'小狗'}obj.say.call(dog)obj.eat.call(dog,'骨头','狗粮')

第一个参数为需要 this 指向需要换到的地方,后面的如果方法需要加参数直接在后面加就可以了

call 方法是会把函数执行一遍的,所以输出

apply

apply 方法和 call 方法不同点仅仅在于参数传递的方式

obj.say.apply(dog)obj.eat.apply(dog,['骨头','狗粮'])

apply 方法的参数传递,需要用 数组包裹,输出是一样的

bind 

bind 方法和 call 方法使用方法是一样的,但是 bind 方法不会调用相关函数,使用 bind 方法后会返回一个函数,我们如果需要执行,直接调用那个函数即可

let dogSay=obj.say.bind(dog)let dogEat=obj.eat.bind(dog,'大骨头','狗粮')dogSay()dogEat()

这样的好处是,用一个变量接收,后续再需要调用,就不用写繁杂的写 call 和 apply 了

输出也是一样的