call、apply、bind 作用和区别
2022-06-19 本文已影响0人
前端末晨曦吖
一、call、apply、bind 的作用
关于call、apply、bind函数,它们主要用来改变this指向的,在很多框架中常有用到,
而且也是面试官喜欢问到的问题:多数会问道三者的区别, 以及手动实现它们。
call的用法
fn.call(thisArg, arg1, arg2, arg3, ...)
<template>
<div>
<button @click="changeThis">点击改变this指向</button>
</div>
</template>
<script>
export default {
data() {
return {
};
},
// 在 `methods` 对象中定义方法
methods: {
changeThis(){
let obj = {
name: "小明",
age: 19,
sayHello: function (job, hobby) {
console.log(`我叫${this.name},今年${this.age}岁。我的工作是: ${job},我的爱好是: ${hobby}。`);
}
}
obj.sayHello('程序员', '开心'); //运行结果 : 我叫小明,今年19岁。我的工作是: 程序员,我的爱好是: 开心。
let obj1 = {
name: "末晨曦吖",
age: 18
}
//call修改this指向了 obj1
obj.sayHello.call(obj1, '前端', '要开心吖'); //运行结果 :我叫末晨曦吖,今年18岁。我的工作是: 前端,我的爱好是: 要开心吖。
}
},
};
</script>
<style scoped>
</style>
apply的用法
apply(thisArg, [argsArr])
fn.apply的作用和call相同:修改this指向,并立即执行fn。区别在于传参形式不同,apply接受两个参数,
第一个参数是要指向的this对象,第二个参数是一个数组,数组里面的元素会被展开传入fn,作为fn的参数。
<template>
<div>
<button @click="changeThis">点击改变this指向</button>
</div>
</template>
<script>
export default {
data() {
return {
};
},
// 在 `methods` 对象中定义方法
methods: {
changeThis(){
let obj = {
name: "小明",
age: 19,
sayHello: function (job, hobby) {
console.log(`我叫${this.name},今年${this.age}岁。我的工作是: ${job},我的爱好是: ${hobby}。`);
}
}
obj.sayHello('程序员', '开心'); //运行结果 : 我叫小明,今年19岁。我的工作是: 程序员,我的爱好是: 开心。
let obj1 = {
name: "末晨曦吖",
age: 18
}
//apply修改this指向了 obj1
obj.sayHello.apply(obj1, ['前端', '要开心吖'] ); //运行结果 :我叫末晨曦吖,今年18岁。我的工作是: 前端,我的爱好是: 要开心吖。
}
},
};
</script>
<style scoped>
</style>
bind的用法
bind(thisArg, arg1, arg2, arg3, ...)
fn.bind的作用是只修改this指向,但不会立即执行fn;会返回一个修改了this指向后的fn。
需要调用才会执行:bind(thisArg, arg1, arg2, arg3, ...)()。bind的传参和call相同。
<template>
<div>
<button @click="changeThis">点击改变this指向</button>
</div>
</template>
<script>
export default {
data() {
return {
};
},
// 在 `methods` 对象中定义方法
methods: {
changeThis(){
let obj = {
name: "小明",
age: 19,
sayHello: function (job, hobby) {
console.log(`我叫${this.name},今年${this.age}岁。我的工作是: ${job},我的爱好是: ${hobby}。`);
}
}
obj.sayHello('程序员', '开心'); //运行结果 : 我叫小明,今年19岁。我的工作是: 程序员,我的爱好是: 开心。
let obj1 = {
name: "末晨曦吖",
age: 18
}
//bind修改this指向了 obj1
obj.sayHello.bind(obj1, '前端', '要开心吖' ); //运行结果 :无输出结果,因为没有调用;call和apply是主动调用,bind是被动调用;
obj.sayHello.bind(obj1, '前端', '要开心吖' )(); //运行结果 :我叫末晨曦吖,今年18岁。我的工作是: 前端,我的爱好是: 要开心吖。
}
},
};
</script>
<style scoped>
</style>
二、call、apply、bind 的区别
相同点:
三个都是用于改变this指向;
接收的第一个参数都是this要指向的对象;
都可以利用后续参数传参。
不同点
call和bind传参相同,多个参数依次传入的;
apply只有两个参数,第二个参数为数组;
call和apply都是对函数进行直接调用,而bind方法不会立即调用函数(所以要手动调用下,前两个是主动调用),而是返回一个修改this后的函数。
修改this的性质不同:
call、apply只是临时的修改一次,也就是call和apply方法的那一次;当再次调用原函数的时候,它的指向还是原来的指向。
bind是永久修改函数this指向,但是它修改的不是原来的函数;而是返回一个修改过后新的函数,此函数的this永远被改变了,绑定了就修改不了。