手写实现call,apply,bind函数

751 阅读1分钟

简单实现具体看下面这个列子:

let objA = {
    name: "肖哥哥",
    age: 20,
    objAFun: function(form, to) {
        console.log(`姓名:${this.name},年龄:${this.age},来自:${form},目的地是:${to}。`);
    }
}
let objB = {
    name: "七叶一枝花",
    age: 23
}

objA.objAFun.myCall(objB, "广州", "广西");
objA.objAFun.myApply(objB, ["上海"]);
objA.objAFun.myBind(objB, ["北京"])();

1,实现call函数

Function.prototype.myCall = function(context) {
    // 判断调用对象objAFun是否为函数
    if(typeof this !== 'function') {
        throw TypeError("typeof error");
    }
    // 获取所有参数
    let args = [...arguments].slice(1);
    let result = null;
    // 判断context上下文是否传入,否则设置为对象函数
    context = context || window;
    // 将调用对象设为对象函数
    context.fn = this;
    // 调用函数
    result = context.fn(...args);
    // 将属性删除
    delete context.fn;
    return result;
}

2,实现apply函数

Function.prototype.myApply = function(context) {
    if (typeof this !== 'function') {
        throw TypeError("type error");
    }
    context = context || window;
    context.fn = this;
    let result = null;
    // 如果有传入参数,则传入参数并调用函数
    if ([...arguments][1]) {
        result = context.fn([...arguments][1])
    } else {
        result = context.fn();
    }
    delete context.fn;
    return result;
}

3,实现bind函数

Function.prototype.myBind = function(context) {
    if (typeof this !== "function") {
        throw TypeError("type error");
    }
    let args = [...arguments].slice(1);
    let fn = this;
    return function Fn() {
        // 根据调用方式,传入不同绑定值
        return fn.apply(this instanceof Fn ? this : context, args.concat(...arguments));
    }
}