Function.prototype.call.call

版权声明:个人笔记,不喜勿喷 https://blog.csdn.net/qq_39571197/article/details/87182630

Function.prototype.call.apply、Function.prototype.apply.call、Function.prototype.apply.apply 同理

        const obj1 = {
            hello: 'obj1',
            sayHello() {
                console.log(this.hello);
            },
        };
        const obj2 = {
            hello: 'obj2',
        };
        const callbackName = Symbol('call-callback');

        /* 代码一 */
        obj1.sayHello.call(obj2);
        /* 分解 */
        obj2[callbackName] = obj1.sayHello;
        obj2[callbackName](/* 参数 */);
        delete obj2[callbackName];

        /* 代码二 */
        Function.prototype.call.call(obj1.sayHello, obj2);
        /* 分解 */
        obj1.sayHello[callbackName] = Function.prototype.call;
        obj1.sayHello[callbackName](obj2);
        /* 等价于,因为调用call的时候也是去原型链找 */
        console.log(obj1.sayHello.call === obj1.sayHello[callbackName]);
        obj1.sayHello.call(obj2); // 循环到 代码一

 实现call、apply

Object.defineProperty(Function.prototype, 'myCall', {
            value(context) {
                const singleTag = Symbol('call-callback');
                context[singleTag] = this;
                /** 
                 * 设置参数,没用展开操作符
                 * 只能参考一下,使用arguments了 */
                let argsPointer = '';
                for (let i = 1; i < arguments.length; i++) {
                    argsPointer += `arguments[${i}],`;
                }
                // argsPointer.slice(0, -1);
                const returnVal = eval(`context[singleTag](${argsPointer})`);
                delete context[singleTag];
                return returnVal;
            },
        });
        Object.defineProperty(Function.prototype, 'myApply', {
            value(context, args) {
                const singleTag = Symbol('apply-callback');
                context[singleTag] = this;
                let returnVal = undefined;
                if (!args) {
                    returnVal = context[singleTag]();
                } else {
                    let argsPointer = '';
                    for (let i = 0; i < args.length; i++) {
                        argsPointer += `args[${i}],`;
                    }
                    // argsPointer.slice(0, -1);
                    returnVal = eval(`this.myCall(context,${argsPointer})`);
                }
                delete context[singleTag];
                return returnVal;
            },
        });
        if (1) {
            const obj1 = {
                hello: 'obj1',
                sayHello(a, b, c) {
                    console.log(a, b, c);
                    console.log(this.hello);
                },
            };
            const obj2 = {
                hello: 'obj2',
            };
            obj1.sayHello.myCall(obj2, 1, 2, 3);
            obj1.sayHello.myApply(obj2, [1, 2, 3]);
        }

 

 

没有更多推荐了,返回首页