上述这三个方法使用对象都是函数,即只有函数可以调用这些方法
首先我们说明 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 了
输出也是一样的