JavaScript手写call、apply、bind方法
实现call()方法
- 将函数设为对象的属性
- 执行并删除这个函数
- 指定this到函数并传入给定参数执行函数
- 如果不传⼊参数,默认指向为 window
// 在Function原型中定义myCall()方法
Function.prototype.myCall = function(target){
// 判断target是否为object
if (typeof target === 'object') {
// 如果为null则让target为window
target = target || window;
} else {
// 如果不是object,则创建一个空对象
target = Object.create(null);
}
// 将this赋值给目标对象中的自定义函数
target.__fn__ = this;
let argArr = []; // 存储参数
for(let i=1; i<arguments.length; i++) {
// 遍历参数存储到argArr数组中
argArr.push(arguments[i]);
}
// 执行自定义函数,传入参数
let result = target.__fn__(...argArr);
// 删除自定义函数
delete target.__fn__;
// 返回结果
return result;
}
实现apply()方法
apply原理与call很相似,只是传递参数格式为数组。
// 在Function原型中定义myApply()方法
Function.prototype.myApply = function(target, arr){
// 判断target是否为object
if (typeof target === 'object') {
// 如果为null则让target为window
target = target || window;
} else {
// 如果不是object,则创建一个空对象
target = Object.create(null);
}
// 将this赋值给目标对象中的自定义函数
target.__fn__ = this;
// 执行自定义函数,传入参数
let result = target.__fn__(...arr);
// 删除自定义函数
delete target.__fn__;
// 返回结果
return result;
}
实现bind()方法
- 创建并返回一个新的函数
- 绑定this,传递预置参数
- bind返回的函数可以作为构造函数使用。故作为构造函数时应使得this失效,但是传入的参数依然有效
Function.prototype.myBind = function(target){
// 判断target是否为object
if (typeof target === 'object') {
// 如果为null则让target为window
target = target || window;
} else {
// 如果不是object,则创建一个空对象
target = Object.create(null);
}
// 将this赋值给目标对象中的自定义函数
target.__fn__ = this;
// 存储myBind中传递的参数
let outerArgs = [];
for(let i=1; i<arguments.length; i++) {
// 遍历参数存储到argArr数组中
outerArgs.push(arguments[i]);
}
// 返回函数
return function(){
// 存储默认传递的参数,比如DOM事件中的event参数
let innerArgs = [];
for(let i=0; i<arguments.length; i++) {
// 遍历参数存储到argArr数组中
innerArgs.push(arguments[i]);
}
// 执行自定义函数,并传递bind中的参数和默认参数
target.__fn__(...outerArgs.concat(innerArgs));
}
}