call、apply、bind 作用和区别
一、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: {
changeThis(){
let obj = {
name: "小明",
age: 19,
sayHello: function (job, hobby) {
console.log(`我叫${this.name},今年${this.age}岁。我的工作是: ${job},我的爱好是: ${hobby}。`);
}
}
obj.sayHello('程序员', '开心');
let obj1 = {
name: "末晨曦吖",
age: 18
}
obj.sayHello.call(obj1, '前端', '要开心吖');
}
},
};
</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: {
changeThis(){
let obj = {
name: "小明",
age: 19,
sayHello: function (job, hobby) {
console.log(`我叫${this.name},今年${this.age}岁。我的工作是: ${job},我的爱好是: ${hobby}。`);
}
}
obj.sayHello('程序员', '开心');
let obj1 = {
name: "末晨曦吖",
age: 18
}
obj.sayHello.apply(obj1, ['前端', '要开心吖'] );
}
},
};
</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: {
changeThis(){
let obj = {
name: "小明",
age: 19,
sayHello: function (job, hobby) {
console.log(`我叫${this.name},今年${this.age}岁。我的工作是: ${job},我的爱好是: ${hobby}。`);
}
}
obj.sayHello('程序员', '开心');
let obj1 = {
name: "末晨曦吖",
age: 18
}
obj.sayHello.bind(obj1, '前端', '要开心吖' );
obj.sayHello.bind(obj1, '前端', '要开心吖' )();
}
},
};
</script>
<style scoped>
</style>
二、call、apply、bind 的区别
相同点:
三个都是用于改变this指向;
接收的第一个参数都是this要指向的对象;
都可以利用后续参数传参。
不同点
call和bind传参相同,多个参数依次传入的;
apply只有两个参数,第二个参数为数组;
call和apply都是对函数进行直接调用,而bind方法不会立即调用函数(所以要手动调用下,前两个是主动调用),而是返回一个修改this后的函数。
修改this的性质不同:
call、apply只是临时的修改一次,也就是call和apply方法的那一次;当再次调用原函数的时候,它的指向还是原来的指向。
bind是永久修改函数this指向,但是它修改的不是原来的函数;而是返回一个修改过后新的函数,此函数的this永远被改变了,绑定了就修改不了。