模拟实现兼容低版本IE浏览器的原生bind()

快乐打工仔 分类:实例代码

模拟实现兼容低版本IE浏览器的原生bind()属于前端实例代码,有关更多实例代码大家可以查看

关于javascript的bind()基本功能可以参阅javascript bind()一章节。

但是此函数是在IE8和IE8以下浏览器中并不支持,下面就介绍一下如何模拟实现此功能。

代码如下:

if(!Function.prototype.bind){
  Function.prototype.bind=function(oThis){
    if (typeof this !== 'function'){
      throw new TypeError('调用者不是当前函数对象');
    }
 
    var aArgs = Array.prototype.slice.call(arguments, 1),
        fToBind = this,
        fNOP = function() {},
        fBound = function() {
          return fToBind.apply(this instanceof fNOP && oThis ? this : oThis||window,           
          aArgs.concat(Array.prototype.slice.call(arguments)));
        };
 
        fNOP.prototype = this.prototype;
        fBound.prototype = new fNOP();
 
    return fBound;
  };
}

上面的代码实现了兼容效果,下面介绍一下它的实现过程。

一.代码注释:

1.if(!Function.prototype.bind),判断当前浏览器是否支持bind()函数。

2.Function.prototype.bind=function(oThis){},如果不支持的话,就添加一个bind函数,参数自然是this要指向的对象。

3.if (typeof this !== 'function'){

  throw new TypeError('调用者不是当前函数对象');

},因为使用call或者apply等方式的存在,可以将调用者转换成其他对象,比如func.bind.call(obj),就是为了防止此情况的出现。

4.var aArgs = Array.prototype.slice.call(arguments, 1),获取为bind函数传递的从第二个开始以后的参数。

5.fToBind = this,将当前函数对象的this引用赋值给变量fToBind 。

6.fNOP = function() {},使用表达式方式创建一个函数,它的用法在后面介绍。

7.fBound = function() {  

  return fToBind.apply(this instanceof fNOP && oThis ? this : oThis||window , 

  aArgs.concat(Array.prototype.slice.call(arguments)));

},fBound函数就是要返回的函数。return fToBind.apply()前面加上return是因为fToBind函数可能会有返回值。

this instanceof fNOP && oThis ? this : oThis||window,this instanceof fNOP可以判断是否用作构造函数,至于&&与运算符后面的oThis 是否需要值得商榷,如果按照MDN的源码的话,当用作构造函数不传递oThis参数的时候,那么会用window对象调用fToBind函数,如果此位置没有oThis,那么无论是否bind()函数传递oThis参数,函数fBound用作构造函数的时候,都能够使用this调用fToBind()函数。

aArgs.concat(Array.prototype.slice.call(arguments)),两个数组进行连接,最终结果就是要传递给fToBind()函数的参数。

8.fNOP.prototype = this.prototype,此句感觉完全没有必要,可能是为了增加原型链的密度。

9.fBound.prototype = new fNOP(),将fBound的原型对象设置为fNOP()的实例对象,这样的话如果fBound 用作构造函数的话,this instanceof fNOP返回值为true。

10.return fBound,返回此函数。

二.相关阅读:

1.typeof运算符的用法参阅javascript typeof一章节。

2.slice()方法参阅javascript slice()一章节。

3.call()方法可以参阅javascript call()一章节。

4.concat()函数可以参阅js数组 concat()一章节。

5.prototype原型可以参阅javascript prototype原型一章节。

模拟实现兼容低版本IE浏览器的原生bind(),这样的场景在实际项目中还是用的比较多的,关于模拟实现兼容低版本IE浏览器的原生bind()就介绍到这了。

回复

我来回复
  • 暂无回复内容