javascript原生bind方法ie低版本兼容详解

上一篇文章讲到了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方法