首页 > 代码库 > 模拟实现兼容低版本IE浏览器的原生bind()函数功能

模拟实现兼容低版本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的Array对象的slice()方法一章节。
3.call()和apply()方法可以参阅javascript的call()和apply()的作用和区别一章节。
4.concat()函数可以参阅js数组的concat()函数的用法一章节。
5.prototype原型可以参阅javascript的prototype原型简单介绍一章节。 

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