温故知新(九二)实现 call,bind,apply
作者:互联网
手动实现 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;
}
标签:function,函数,温故知新,call,context,九二,prototype,fn 来源: https://blog.csdn.net/MFWSCQ/article/details/108443151