0
点赞
收藏
分享

微信扫一扫

原生JS - 封装call、apply、bind方法

IT程序员 2021-09-24 阅读 92

1、call、apply、bind区别

  • call、apply

    • 直接执行函数,替代函数中的this
    • 一般应用于要即时执行的函数中替代this
    • call和apply的第一个参数都是为了替换函数中的this指向
    • call的其他参数正常传入,apply的其他参数以数组方式传入
    function fn(a, b) {
        this.a = a;
        this.b = b;
        console.log(this);
        return this;
    }
    
    /* 直接执行函数 */
    fn(3, 5); // 结果:Window
    console.log(a, b); // 结果:3 5
    // 函数执行后,this指向window,此时a和b是window下的属性,可以直接打印出来
    
    /* 如果使用call或apply */
    // call和apply的第一个参数是为了替换函数中的this指向
    
    // call
    fn.call({}, 5, 9); // 结果:{a: 3, b: 5}
    // apply
    fn.apply({}, [12, 15]); // 结果:{a: 12, b: 15}
    
  • bind

    • 返回一个新函数,这个函数中的this都被替代为绑定的对象,当执行时this就会全部指向这个对象
    • 一般用于回调函数中替代this指向
    function fn(a, b) {
        this.a = a;
        this.b = b;
        return this;
    }
    
    var fn1 = fn.bind({});
    var obj = fn1(3, 5);
    console.log(obj); // 结果:{a: 3, b: 5}
    
    // 在开发过程中,常见的还有以下写法
    var obj2 = fn.bind({})(3, 5);
    console.log(obj2); // 结果:{a: 3, b: 5}
    

2、方法封装

  • call

    Function.prototype.callHarvey = function (obj) {
        // 如果该方法的调用者不是一个函数,则抛出错误信息
        if (typeof this !== "function") throw new Error(this + "is not a function!");
        
        // 重定向this
        var _this = Object(obj) || window;
        
        // 创建一个新数组,用于获取第一个参数后的所有参数
        var newArr = [];
        
        // 将call的调用函数传给重新定向的this
        _this.callback = this;
        
        // 遍历arguments,第一个之后的参数push到newArr中
        for (let i = 1; i < arguments.length; i++) newArr.push(arguments[i]);
        
        // 使用apply方法,传入重新定向的this和newArr
        _this.callback.apply(_this, newArr);
        
        // 清除callback,防止污染this指向的对象
        delete _this.callback;
    }
    
  • apply

    Function.prototype.applyHarvey = function (obj, initArr) {
        // 如果该方法的调用者不是一个函数,则抛出错误信息
        if (typeof this !== "function") throw new Error(this + "is not a function!");
        
        // 重定向this
        var _this = Object(obj) || window;
          
        // 如果没有传入其他参数,则将一个空数组赋值给arr
        var arr = initArr || [];
        
        // 将call的调用函数传给重新定向的this
        _this.callback = this;
        
        // 使用ES6进行解构赋值,执行_this.callback
        _this.callback(...arr);
        
       // 防止污染this指向的对象
        delete _this.callback;
    }
    
  • bind

    Function.prototype.bindHarvey = function (obj) {
        // 如果该方法的调用者不是一个函数,则抛出错误信息
        if (typeof this !== "function") throw new Error(this + "is not a function!");
        
        // 重定向this
        var _this = Object(obj) || window;
        
        // 将call的调用函数传给重新定向的this
        _this.callback = this;
        
          // 返回函数
        return function () {
            _this.callback.apply(_this, Array.from(arguments));
            
            // 防止污染this指向的对象
          delete _this.callback;
        }
    }
    
举报

相关推荐

0 条评论