这三个方法的区别
首先说下bind与call的区别 call和apply都是为了解决改变this的指向。它们的作用是相同的。只是他们传的参数的方式不同。第一个参数都是要指向的对象。apply的第二个参数为要传递的参数数组,而call则是将这个数组进行拆分为第二、第三、第四、...、第N个参数传递。
let student = {
name: '小明'
};
function getStudentInfo(age, height) {
console.log('年龄' + age);
console.log('身高' + height);
console.log('姓名' + student.name);
};
getStudentInfo.call(student, 24, '178cm');
getStudentInfo.apply(student, [24, '178cm'])
// 运行后的结果
年龄24
身高178cm
姓名小明
年龄24
身高178cm
姓名小明
至于bind方法,他是直接改变这个函数的this指向并且返回一个新的函数,不是直接调用立刻执行,之后再次调用这个函数的时候this都是指向bind绑定的第一个参数。bind传餐方式跟call方法一致。
如何在es3中自己实现bind函数
if (!Function.prototype.bind) {
Function.prototype.bind = function () {
var self = this, // 保存原函数
context = [].shift.call(arguments), // 保存需要绑定的this上下文
let args = [].slice.call(arguments); // 剩余的参数转为数组
return function () { // 返回一个新函数
self.apply(context,args);
}
}
}
如何自己实现call函数
Function.prototype.myCall = function(context) {
context.fn = this;
let args = [...arguments].slice(1);
let result = context.fn(...args);
delete context.fn
return result
}
如何自己实现apply函数
Function.prototype.myApply = function(context) {
context.fn = this;
let args = arguments[1];
if (Object.prototype.toString.call(args).slice(8, 13) !== 'Array') {
throw new Error('参数有误');
}
let result = context.fn(...args);
delete context.fn
return result
}
// 测试
var b = {
value: 2
};
function getb(age) {
console.log(age)
console.log(this.value)
}
getb.myApply(b, [5,4]); //5 4, 2
getb.myApply(b, 3); //抛出错误