手动实现 call,bind,apply
答案:
call() 方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。该方法的语法和作用与 apply() 方法类似,只有一个区别,就是 call() 方法接受的是一个参数列表,而 apply() 方法接受的是一个包含多个参数的数组。
Function.prototype.myCall = function(context,...args){
//谁调用的call,谁就是这个this,必须是一个function,比如:fn.call(obj,1,2,3),这时候fn就是我们拿到的this
if(typeof this !== 'function'){
throw new TypeError('not function!');
}
const fn = this;
let result = null;
context = context || window;
//把fn 赋值给传入的要绑定的this对象,所以fn里面的fn就变成了 上面传入的context
context.fn = fn;
//执行fn
result = context.fn(...args);
//删除context.fn属性,解除引用
delete context.fn;
//返回执行结果
return result;
}
bind() 方法创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。
使用apply:
if (!Function.prototype.bind) (function(){
var slice = Array.prototype.slice;
Function.prototype.bind = function() {
var thatFunc = this, thatArg = arguments[0];
var args = slice.call(arguments, 1);
if (typeof thatFunc !== 'function') {
// closest thing possible to the ECMAScript 5
// internal IsCallable function
throw new TypeError('Function.prototype.bind - ' +
'what is trying to be bound is not callable');
}
return function(){
var funcArgs = args.concat(slice.call(arguments))
return thatFunc.apply(thatArg, funcArgs);
};
};
})();
思路
1.拷贝源函数:
-
通过变量储存源函数
-
使用Object.create复制源函数的prototype给fToBind
2.返回拷贝的函数
3.调用拷贝的函数:
-
new调用判断:通过instanceof判断函数是否通过new调用,来决定绑定的context
-
绑定this+传递参数
-
返回源函数的执行结果
Function.prototype.myBind = function (objThis, ...params) {
const thisFn = this; // 存储源函数以及上方的params(函数参数)
// 对返回的函数 secondParams 二次传参
let fToBind = function (...secondParams) {
console.log('secondParams',secondParams,...secondParams)
const isNew = this instanceof fToBind // this是否是fToBind的实例 也就是返回的fToBind是否通过new调用
const context = isNew ? this : Object(objThis) // new调用就绑定到this上,否则就绑定到传入的objThis上
return thisFn.call(context, ...params, ...secondParams); // 用call调用源函数绑定this的指向并传递参数,返回执行结果
};
fToBind.prototype = Object.create(thisFn.prototype); // 复制源函数的prototype给fToBind
return fToBind; // 返回拷贝的函数
};
apply() 方法调用一个具有给定 this 值的函数,以及以一个数组(或类数组对象)的形式提供的参数。
Function.prototype.myApply = function(context,argArr){
if(typeof this !== 'function'){
throw new TypeError('not function');
}
if(argArr && !Array.isArray(argArr)){
throw new TypeError('the second argument need an array');
}
const fn = this;
let result = null;
context = context || window;
argArr = argArr || [];
context.fn = fn;
result = context.fn(...argArr);
delete context.fn;
return result;
}
本文详细介绍了如何在JavaScript中手动实现call()、bind()和apply()方法,包括它们的工作原理、示例代码和应用场景。重点讲解了如何绑定this值和传递参数,以及bind()方法的特性。

被折叠的 条评论
为什么被折叠?



