简单的自我实现call apply和bind

183 阅读1分钟

    Function.prototype.myCall = function (obj, ...arg) {
        obj = obj || window;
        const fn = Symbol();
        obj[fn] = this;
        const result = obj[fn](...arg);
        delete obj[fn];
        return result;
    };

    Function.prototype.myApply = function (obj, arg) {
        obj = obj || window;
        const fn = Symbol();
        obj[fn] = this;
        let result;
        result = !arg ? obj[fn]() : obj[fn](...arg);
        delete obj[fn];
        return result;
    };

    Function.prototype.myBind = function (...arg) {
        let obj = arg[0] || window;
        const fn = Symbol();
        obj[fn] = this;
        const partial = (func) => {
            return ( ...___arg) => {
                delete obj[fn];
                return func.call(arg[0], ...arg.slice(1), ...___arg);
            };
        };
        return partial(obj[fn]);
    };

    // 测试一下
    var value = 2;

    var obj = {
        value: 111
    };

    function bar(name, age) {
        console.log(this.value, "----");
        return {
            value: this.value,
            name: name,
            age: age
        };
    }

    bar.value = 999;
    // bar.myCall(null); // 2

    console.log(bar.myApply(obj, ["bob", 18])); //{value: 111, name: "bob", age: 18}
    console.log(bar.myCall(obj, "bob", 18)); //{value: 111, name: "bob", age: 18}
    console.log(bar.myBind(obj, "bob", 18)()); //{value: 111, name: "bob", age: 18}