zoukankan      html  css  js  c++  java
  • call、apply、bind的区别,模拟call、apply和bind的实现

    bind:bind绑定完this的指向后会返回一个新的函数体,不会被立即调用
     
    call&apply:绑定完this的指向后会立即调用
     
    call与apply的区别:
        call:第一个参数是this的指向,第二个以及后面的所有参数需要一个个进行传递
     
        apply:第一个参数是this的指向,第二个参数是一个数组
     
    不传参的方法:
    Function.prototype.bind2 = function (context) {
        var self = this;
        return function () {
            return self.call(context);
        }
    
    }
    传参的方法:
    Function.prototype.myBind = function (objCtx) {
        if (typeof this !== 'function') {
            throw new TypeError('Error');
        }
        let ctx = objCtx || window;
        let _this = this;
        let args = [...arguments].slice(1);
        
        let Fbind = function () {
            let self = this instanceof Fbind ? this : ctx;
            return _this.apply(self, args.concat(...arguments));
            // 这里可以使用 call 方法
            // let bindArgs = args.concat(...arguments);
            // return _this.call(self, ...bindArgs);
        }
        
        let f = function () {};
        f.prototype = this.prototype;
        Fbind.prototype = new f();
        
        return Fbind;
    }
     

    以上就是 call 的思路,apply 的实现也类似

    不传参的方法:
    Function.prototype.bind2 = function (context) {
        var self = this;
        return function () {
            return self.apply(context);
        }
    
    }
    传参的方法:
    Function.prototype.myBind = function (objCtx) {
        if (typeof this !== 'function') {
            throw new TypeError('Error');
        }
        let ctx = objCtx || window;
        let _this = this;
        let args = [...arguments].slice(1);
        
        let Fbind = function () {
            let self = this instanceof Fbind ? this : ctx;
            return _this.apply(self, args.concat(...arguments));
            // 这里可以使用 call 方法
            // let bindArgs = args.concat(...arguments);
            // return _this.apply(self, ...bindArgs);
        }
        
        let f = function () {};
        f.prototype = this.prototype;
        Fbind.prototype = new f();
        
        return Fbind;
    }
     

    bind 和其他两个方法作用也是一致的,只是该方法会返回一个函数。并且我们可以通过 bind 实现柯里化。

    同样的,也来模拟实现下 bind

     
    Function.prototype.myBind = function (context) {
      if (typeof this !== 'function') {
        throw new TypeError('Error')
      }
      var _this = this
      var args = [...arguments].slice(1)
      // 返回一个函数
      return function F() {
        // 因为返回了一个函数,我们可以 new F(),所以需要判断
        if (this instanceof F) {
          return new _this(...args, ...arguments)
        }
        return _this.apply(context, args.concat(...arguments))
      }
    }
    如何准确的判断一个对象是一个什么类型的?
    1、typeof  
    
    2、instanceof    var a=[1,2];console.log(a instanceof Array)  //true
    3、Object.prototype.toString.call()    var arr = [10,20,03,04]; var fn = function(){} var img = new Image() var d = new Date() console.log(arr.toString()) console.log(Object.prototype.toString.call(d))
     
  • 相关阅读:
    Objective-C 生成器模式 -- 简单实用和说明
    Objective-C 桥接模式 -- 简单实用和说明
    Objective-C 工厂模式(下) -- 抽象工厂模式
    Objective-C 工厂模式(上) -- 简单工厂模式
    Linux篇---Vi的使用
    【Spark篇】---SparkSQL中自定义UDF和UDAF,开窗函数的应用
    【Spark篇】---SparkStreaming算子操作transform和updateStateByKey
    【Spark篇】---SparkStream初始与应用
    【Spark篇】---SparkSQL on Hive的配置和使用
    【Spark篇】---Spark中Shuffle机制,SparkShuffle和SortShuffle
  • 原文地址:https://www.cnblogs.com/houjl/p/10086576.html
Copyright © 2011-2022 走看看