共同点,众所周知都是改变this的指向(也就是函数执行时的上下文)
区别,就先看看传参吧~
call:
call接受的是一个参数列表,其中第一个参数表示函数运行时的this值;
如果没有传入第一个参数,this 的值将会被绑定为全局对象.
如:
Function.call(thisArgs,args1,arg2...)
返回值:使用调用者提供的 this 值和参数调用该函数的返回值,没有则返回undefined。
例如:使用call调用父构造函数(继承)
function Product(name,price) {
this.name = name;
this.price = price;
}
function Food(name,price) {
Product.call(this,name,price); // 调用父构造函数
this.category = 'food';
}
var cheese = new Food('feta',5);
// { name: 'feta', price: 5, category: 'food' }
apply:
apply接受的是一个参数数组;第一个参数也是表示给定this的值
// 获取数组中的最大值
const number = [5,6,7,2,3,1];
const max = Math.max.apply(null,numbers) // 7
返回指定this和参数的函数结果
例如:使用apply将数组各项添加到另一个数组(合并两数组)
var array = ['a','b'];
var elements = [1,2,3];
array.push.apply(array,elements);
console.log(array); // [ 'a', 'b', 1, 2, 3 ]
apply与call的区别在于提供参数的方式,apply使用的是参数数组,可以使用数组字面量或者数组对象;call使用的是参数列表。
bind:
bind()创建一个新函数,在调用时设置this关键字为提供的值
如果 bind 的第一个参数是 null 或者 undefined,this 就指向全局对象 window。
function add (a, b) {
return a + b;
}
function sub (a, b) {
return a - b;
}
var c = add.bind(sub, 5, 3); // 这时,并不会返回 8
var d = add.bind(sub, 5, 3)(); // 调用后,返回 8
console.log(c,d);
bind返回值是个函数,需要后续调用才会执行,否则不会执行。
总结:
以上三者的共同点都是改变对象的执行上下文(this),call跟apply是立即执行,并返回函数的执行结果。bind返回的是一个函数,需要自己手动调用该函数才能执行。
利用apply一行代码实现bind:
// 手动实现bind
Function.prototype.fakeBind = function(obj) {
return (...args) => this.apply(obj, args)
}
// 测试 bind
function testBind(args) {
console.log(this.a,args);
}
testBind.bind({a:3})(4); // 3,4
testBind.fakeBind({a:3})(4); // 3,4