• Function.bind 方法


    this.num = 9; 
    var mymodule = { num: 81, getNum: function() { return this.num; } }; module.getNum(); // 81 var getNum = module.getNum;
    getNum();
    // 9, 因为在这个例子中,"this"指向全局对象 // 创建一个'this'绑定到module的函数 var boundGetNum = getNum.bind(module);
    boundGetNum();
    // 81
    if(!Function.prototype.bind){
    
      Function.prototype.bind = function(oThis){
    
        if(typeof this !=="function"){ //如果不函数抛出异常
    
          throw new TyperError("")
    
        }
    
        var aArgs = Array.prototype.slice.call(arguments,1),   //此处的aArgs是除函数外的参数
    
          fToBind = this,                  //要绑定的对象
    
          fNOP = function(){},
    
          fBound = function(){
    
            return fToBind.apply(
              //没看清楚为什么要 this. instanceof fNOP ? this: oThis, 应该直接OThis吧
              this instanceof fNOP ? this:oThis||this,         aArgs.concat(Array.prototype.slice.call(arguments))  参数合并 );
    
              )
    
          };
    
        fNOP.prototype = this.prototype;  // 利用中间函数 fNOP 来借用 被执行函数ABC的原型
    
        fBound.prototype = new fNOP();   // 因为 new FNOP ( ) 这个实例有个属性 __proto__ 指向了 fNOP的原型, 这样改变fBound的原型不会影响到 被执行函数ABC的原型
    
        return  fBound;
    
      }
    
    }

    明白 bind 的用法就必须要知道 apply 的用法,MDN 指出,apply 是直接修改了函数内部的指向到第一个参数,并将第二个参数数组传参进函数并运行这个函数。也就是说

    var obj = {test: function() { console.log(this, arguments) }},
        func = obj.test;
    
    obj.test("Hello", ",", "world", "!");
    func.apply(obj, ["Hello", ",", "world", "!"]);
    

    这两种运行方式是一样的。那么回到 Polyfill 中发现参数的写法是 args.concat(slice.call(arguments))args 是将 bind时候定义的除第一个参数外的其它参数,而此时的 arguments 是指函数调用时候的参数,通过数组的操作将这两个参数合并成一个数组传入函数内部。看个例子你可能更容易明白:

    /** 代码接上 **/
    var newFunc = func.bind(obj, "Hello", ",");
    newFunc("world", "!");
    

    那么再来回答问题一,这个是典型的属性继承的方法,本来使用

    bound.prototype = self.prototype
    

    就可以将原属性集成过来了,但是这样两个对象属性都指向同一个地方,修改 bound.prototype 将会造成 self.prototype也发生改变,这样并不是我们的本意。所以通过一个空函数 nop 做中转,能有效的防止这种情况的发生。

    bind返回的是函数

    if (!Function.prototype.bind) {
        Function.prototype.bind = function(obj) {
            var _self = this
                ,args = arguments;
            return function() {
                _self.apply(obj, Array.prototype.slice.call(args, 1));
            }
        }
    }
  • 相关阅读:
    Java基础五
    Java基础测试
    Java练习题
    Java基础四
    Java基础三
    Java基础二
    Java基础一
    大数据讲解
    python笔记之函数 二
    iOS UICollectionView的使用(用storyboard和xib创建)
  • 原文地址:https://www.cnblogs.com/dhsz/p/7060652.html
Copyright © 2020-2023  润新知