call
Function.Prototype.myCall = function(context) {
// this 参数可以传 null,当为 null 的时候,视为指向 window
const context = context || window;
context.fn = this;
// 对参数进行处理
const args = [];
for(let i = 1, len = arguments.length; i < len; i++) {
args.push(arguments[i]);
}
let result = arguments.length > 0 ? context.fn(...args) : context.fn();
delete context.fn;
return result;
}
apply
Function.Prototype.myApply = function(context, arr) {
// this 参数可以传 null,当为 null 的时候,视为指向 window
const context = context || window;
context.fn = this;
let result = arr.length > 0 ? context.fn(...arr) : context.fn();
delete context.fn;
return result;
}
bind
简单实现
Function.prototype.myBind = function(context){
self = this; //保存this,即调用bind方法的目标函数
return function(){
return self.apply(context, [...arguments]);
};
};
函数柯里化的实现
Function.prototype.myBind = function(context){
// 使用闭包存下初始参数
const args = Array.prototype.slice.call(arguments, 1),
self = this;
return function() {
// 再次调用时
const innerArgs = Array.prototype.slice.call(arguments);
const finalArgs = args.concat(innerArgs);
return self.apply(context,finalArgs);
};
};
构造函数的实现
Function.prototype.myBind = function(context){
// 判断是否为函数
if(typeof this !== 'function') {
throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
}
const args = Array.prototype.slice(arguments, 1);
self = this;
bound = function() {
const innerArgs = Array.prototype.slice.call(arguments);
const finalArgs = args.concat(innerArgs);
// 判断this,如果是,则传递this即实例化的对象。
return self.apply((this instanceof F ? this : context), finalArgs);
};
// 处理原型链
let F = function(){};
F.prototype = self.prototype;
bound.prototype = new F();
retrun bound;
};
ES6实现
Function.prototype.myCall = function (context, ...args) {
context = context || window;
const fnSymbol = Symbol("fn");
context[fnSymbol] = this;
const result = context[fnSymbol](...args);
delete context[fnSymbol];
return result;
}
结合实现
Function.prototype.myBind = function(context, ...args){
self = this;
return function() {
context = context || window
const fnSymbol = Symbol('fn')
context.fnSymbol = self
const result = context[fnSymbol](...args)
delete context[fnSymbol]
return result
};
};