上一篇文章讲到了javascript原生的bind方法: javascript
http://www.cnblogs.com/liulangmao/p/3451669.htmlhtml
这篇文章就在理解了原生bind方法的原理之后,本身写一个原型bind方法,来兼容ie低版本浏览器:java
bind方法一共作了三件事:web
1.改变方法中的上下文浏览器
2.为方法传入实参app
3.返回一个改变了上下文而且调用的时候传入指定的实参的新方法函数
所以,咱们就照着这个思路,写一个Function的原型方法:this
if(!Function.prototype.bind){ Function.prototype.bind= function(obj){ //保存调用bind的方法 var self = this; //保存调用bind时的参数 var selfArg = Array.prototype.slice.call(arguments,1); //当使用new方式来调用bind后的方法,须要使用bridge来继承self的原型; var bridge = function(){}; bridge.prototype = self.prototype; //建立新的函数 var _self = function(){ //调用新函数时,将调用新函数时传入的参数和bind时的参数合并 var newArg = selfArg.concat(Array.prototype.slice.call(arguments)); //返回执行self方法,改变指针和参数 //若是是使用new方法调用,那么this上下文就是实例化之后的实例,而不是bind时传入的obj,这个暂时想不到有什么例子须要这样调用 return self.apply(this instanceof bridge? this : obj||{} , newArg) }; _self.prototype = new bridge(); //返回新建立的函数 return _self; } }
下面来看下使用bind的结果:spa
var intro = function(age){ //arguments[arguments.length-1]能够用来访问事件对象 //bind方法会把执行方法时的参数放在bind时传入的参数的后面,而后一块儿执行,因此,事件对象做为触发事件时传入的参数,它就是最后一个参数, //而且使用这种方式访问事件对象无需考虑兼容性问题 alert(arguments[arguments.length-1].clientX); alert(this.name+','+this.job+','+age); }; var jyh = {name:'jyh',job:'web-front-end'}; var introOther = intro.bind(jyh,18); if(document.addEventListener){ document.addEventListener('mousedown',introOther); } else{ document.attachEvent('onmousedown',introOther) } //若是使用new方式来调用,那么this指针指向zxg实例 var zxg = new introOther();
这样就作到了在任意浏览器中使用bind方法prototype