实现call-bind-apply

5 阅读1分钟

call和bind和apply常用在改变this的指向,那么你会手写他的代码吗?自己模拟实现

call代码
 // 切记不可以用箭头函数,因为箭头函数没有自己的this
        Function.prototype.myCall = function(context,...args){
            // 判断context的类型,其中globalThis是原生全局对象,如果是window指的是windos,如果是node,指的是global
            context = (context === null || context === undefined) ? globalThis : Object(context); 
            const fn = this; // fn指向调用myCall的函数
            let key = Symbol(); // 创建一个唯一标识,防止冲突
            Object.defineProperty(context, key, {
                value: fn,
                enumerable: false, // 不可枚举
            });
            // 执行函数
            const result = context[key](...args);
            // 删除key属性
            delete context[key];
            // 返回结果值
            return result;

        }

        let obj = {
            name: '张三',
            age: '23'
        };

        function getFullName() {
            return `${this.name}-${this.age}`;
        }

        let result = getFullName.myCall(obj);
        console.log(result); // 输出: '张三-23'
Function.prototype.myBind = function(context,...args){
            let fn = this;
            return function(...restArgs){
                if(new.target){
                    // 如果是通过news调用
                    return new fn(...args,...restArgs);
                }
                return fn.myCall(context,...args,...restArgs);
            }
        }

        let obj = {
            name: '张三',
            age: '23'
        };

        function getFullName() {
            return `${this.name}-${this.age}`;
        }
        // myBind是要返回一个函数
        let result = getFullName.myBind(obj);
        console.log(new result()); // 输出: '张三-23'