(function(){
                if (!Function.prototype.bind) {
alert(1);
                    Function.prototype.bind = function(obj){
alert(2);
                        var owner = this, args = Array.prototype.slice.call(arguments), 
              callobj = Array.prototype.shift.call(args);
                        return function(e){
alert(1);
                            e = e || top.window.event || window.event;
                            owner.apply(callobj, args.concat([e]));
                        };
                    };
                }
            })();

解决方案 »

  1.   

     
    (function(){
          if (!Function.prototype.bind) { //判断有没有加过bind属性
              alert(1);
              Function.prototype.bind = function(obj){
                  alert(2);
                  var owner = this, args = Array.prototype.slice.call(arguments), 
                       callobj = Array.prototype.shift.call(args); //取第一参数
                  return function(e){
                      alert(1);
                      //判断用e取从左到右有值的第一个
                      e = e || top.window.event || window.event;
                      //函数的当前对象为callobj也就是第一个参数,并传后面的参数
                      owner.apply(callobj, args.concat([e]));
                  };
              };
          }
      })();
      

  2.   

    (1)js函数具有一些常规的属性和方法,比如length属性(表示函数参数的个数)和call,apply方法(转换函数的this对象),这些属性方法都来自js函数的原型上,即Function.prototype。简单来讲,这段代码的意思就是:
    检查函数原型中是否存在名叫bind的方法,如果存在什么都不执行,如果不存在就给原型加上一个bind方法。
    调用bind的结果是返回一个新函数,新函数中将‘调用bind的函数的this’指定为‘调用时传到bind中的参数的第一个参数’,将‘调用bind的函数的参数’指定为‘调用时传到bind中的所有参数+e(事件对象)’。(2)可以自己做个小例子(前提是要保证if(...)可以顺利执行,可以找一个版本较低的浏览器),看一下:function foo(){
        alert(this.length)
    };//调用bind;
    foo.bind('b','c');//因为bind方法返回一个新函数(可以通过consloe.log(foo.bind('b','c')))在控制台里检测一下,
    //所以可以如下所示执行新函数。
    //返回的新函数执行时,实际上是在执行:foo.apply('b',['b','c',e]),
    //此时foo内部的this指向了'b'所以最后弹出的是1(字符串b的length)。
    //因为foo在定义时并没有指定要传参,所以在这里['b','c',e]就没有什么意义了。
    foo.bind('b','c')();//弹出:1
      

  3.   


    先谢谢阿鱼详细回答,我这么测的
            Function.prototype.bind = function(obj){
                    var owner = this,
    args = Array.prototype.slice.call(arguments); 
    console.log(args);//[o { num=1}, 2]
          var callobj = Array.prototype.shift.call(args);//o { num=1}
    console.log(args);//[2]
                    return function(e){
                        e = e || top.window.event || window.event;
    console.log(e);//undifined 这里怎么回事?没有获取到event对象
                        owner.apply(callobj, args.concat([e]));//等同于fn.apply(o,[2,e])是吧
                        console.log(args.concat([e]));
                    };
                };

                function o(){
                    this.num = 1;
                    this.fn = function(arg){
                        alert(this.num + arg)
                    }.bind(this, 2);
                }
    var ofn = new o();
    ofn.fn();
    有两个问题:1、event对象没获取到,undefined..
    2、事件对象在这里具体什么用途?
    3,这个为函数原型新增的bind方法有什么应用场景?
    js学得疏浅.谢谢解答...
      

  4.   

    谢谢回答;
    我是这样测的. Function.prototype.bind = function(obj){
                    var owner = this,
    args = Array.prototype.slice.call(arguments); 
    console.log(args);//[o { num=1}, 2]
           var callobj = Array.prototype.shift.call(args);//o { num=1}
    console.log(args);//[2]
                    return function(e){
                        e = e || top.window.event || window.event;
    console.log(e);//undifined 这里怎么回事?没有获取到event对象
                        owner.apply(callobj, args.concat([e]));//等同于fn.apply(o,[2,e])是吧
                        console.log(args.concat([e]));
                    };
                };            function o(){
                    this.num = 1;
                    this.fn = function(arg){
                        alert(this.num + arg)
                    }.bind(this, 2);
                }
    var ofn = new o();
    ofn.fn();1、event对象没获取到,undefined..
    2、事件对象在这里具体什么用途?
    3,这个为函数原型新增的bind方法有什么应用场景?
      

  5.   

     event要在IE的事件下有值
     函数原型新增的方法为了调用方便
    下面例子:给body的onclick邦定一个方法,响应是可以传参数点我
    <script>
     (function(){
                    if (!Function.prototype.bind) {
                      
                        Function.prototype.bind = function(obj){
                    
                            var owner = this, args = Array.prototype.slice.call(arguments), 
                                 callobj = Array.prototype.shift.call(args);
                            return function(e){
                                alert(1);
                                e = e || top.window.event || window.event;
                                owner.apply(callobj, args.concat([e]));
                            };
                        };
                    }
    })();
    function  OnClick(a,b,c){
    alert(  this.tagName + ':'+( a+b+c )  );
    }
     document.body.onclick=OnClick.bind(document.body,1,2,3);
    </script>
      

  6.   

    bind 的方法是修改函数的上下文(也就是this)对象,一般用于事件绑定等地方,事件绑定的this指向事件源,但很多情况下你不想这样做而想换一个this,那就要用bind了。
    <input type="button" name="NotBind" id= "notBind" value="Not bind">
    <input type="button" name="Bind" id= "bind" value="Bind"><SCRIPT type="text/javascript">
    <!--
    (function(){
    if (!Function.prototype.bind) {
    alert(1);
    Function.prototype.bind = function(obj){
    alert(2);
    var owner = this, args = Array.prototype.slice.call(arguments), 
     callobj = Array.prototype.shift.call(args);
    return function(e){
    alert(1);
    e = e || top.window.event || window.event;
    owner.apply(callobj, args.concat([e]));
    };
    };
    }
    })();var ob = {
    name:"'This' is the object ob, not the button"
    }var find= function (name) {
    return document.getElementById(name);
    }find("notBind").onclick= function () {
    alert(this.name);
    }find("bind").onclick= (function () {
    alert(this.name);
    }).bind(ob);
    //-->
    </SCRIPT>
      

  7.   

    谢谢ftiger君很好的示例,bind方法的作用了解了,可否细致拓下这个事件对象的用法啊..查了些资料总觉得自己没理解好..<原型、继承正边看书边理解,事件虽然普通的用到但理解的不到位...再次感谢...>
      

  8.   

    主要是多个控件组合成一个大对象(类)的时候使用,将事件的this从控件转换到这个大对象身上。特别是这个大对象内部还有些数据的时bind了之后代码更方便。当然绑定不能用我给你的代码例子,要不很可能在IE67下会有内存泄露(循环引用问题),最好用各种框架提供的绑定方法。
      

  9.   

    (1)这个bind的方法主要意义在于转换函数的this对象,6楼的例子已经清楚的展示了。至于bind在最后返回新函数“return function(e){...}”时传入的参数e以及对e的定义“e = e || top.window.event || window.event;”,其意义在于传递e即事件对象。可以继续用6楼的代码来说明:
    6楼是用bind给input按钮添加了单击事件函数(弹出name值),原代码我们不动,只在“find("bind")...”这个地方加一点点东西,如下://修改之前的原代码:
    find("bind").onclick= (function () {
        alert(this.name);
    }).bind(ob);//修改之后:传入了参数e,并加了一行alert(e.clientX)
    find("bind").onclick= (function (e) {
        alert(this.name);
        //下面为新代码,client是事件对象的属性,
        //意思是事件发生时鼠标相对于屏幕的横坐标的值,在这里就是单击按钮时鼠标的横坐标
        alert(e.clientX);
    }).bind(ob);修改后,单击#bind按钮,新代码成功执行,既弹出了name的值,也弹出了鼠标坐标。其实我们加的事件对象e就来自在原型中定义bind方法时“return function(e){...}”中的e。
    下面我们来验证一下,很简单去掉bind定义时传入的e:            return function(){//去掉了参数e
                    alert(1);
                    e = e || top.window.event || window.event;
                    owner.apply(callobj, args.concat([e]));
                };然后,当再点击#bind按钮时,发现代码不执行了,而且浏览器报错"e is not defined";这恰恰能验证e来自bind定义时返回的新函数中的参数e。其实到这里,就比较清晰了://给按钮绑定的事件函数并不是
    //find("bind").onclick= 
    (function (e) {
        alert(this.name);
        alert(e.clientX)
    }).bind(ob)//而是
    function(e){
      e = e || top.window.event || window.event;
      (function (e) {
        alert(this.name);
        alert(e.clientX)
       }).apply(ob, [e]);
    }
    //所以按钮的单击事件对象e是存在于这个函数中的而不是onclick后面的函数,如果想进行关于事件对象e的操作只能在bind返回的新函数中进行。但是bind是为所有函数定义的公有方法,不可能为了某个按钮的操作在里面进行对e的操作,所以把e(代码中的(obj,[e]))传给了调用bind方法的函数(也就是onclick后的函数),这样就可以在自己定义的函数里对e进行任意操作了。
    (2)之前在一些较早的js类库里,都有相似的bind扩展方法。而且,事实上在javascript-1.8.5版本后就已经在函数原型中增加了bind方法(部分浏览器不支持比如ie6-8),该bind方法与楼主的bind有点出入,不过主要功能也是为了转移this。
    楼主可以参考下:
    https://developer.mozilla.org/zh-CN/docs/JavaScript/Reference/Global_Objects/Function/bind(英文版--Mozilla)
    http://msdn.microsoft.com/zh-cn/library/ie/ff841995(v=vs.94).aspx(汉译--MS)