上一篇文章讲到了javascript原生的bind方法:
http://www.cnblogs.com/liulangmao/p/3451669.html
这篇文章就在理解了原生bind方法的原理以后,自己写一个原型bind方法,来兼容ie低版本浏览器:
bind方法一共做了三件事:
1.改变方法中的上下文
2.为方法传入实参
3.返回一个改变了上下文并且调用的时候传入指定的实参的新方法
因此,我们就照着这个思路,写一个Function的原型方法:
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的结果:
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方法