理解 backbone.js 中的 bind 和 bindAll 方法

在backbone.js的学习过程中,被bind和bindAll弄得有点晕,这里包括underscore.js的bind和bindAll,以及JQuery提供的bind方法。

在一篇En博客中学习,写下这篇笔记

  1. 首先说熟悉的JQuery的bind,引用api帮助文件的内容即可很清晰地理解其使用意义和方法:

     dom.bind(type,[data],function(eventObject));
      
     dom.bind(type,[data],false);
      
     dom.bind(events);
      
      
     //例子
      
     //当每个段落被点击的时候,弹出其文本:
     $("p").bind("click", function(){
       alert( $(this).text() );
     });
      
     //同时绑定多个事件类型:
     $('#foo').bind('mouseenter mouseleave', function() {
       $(this).toggleClass('entered');
     });
      
     //同时绑定多个事件类型/处理程序:
     $("button").bind({
       click:function(){$("p").slideToggle();},
       mouseover:function(){$("body").css("background-color","red");},  
       mouseout:function(){$("body").css("background-color","#FFFFFF");}  
     });
      
     //你可以在事件处理之前传递一些附加的数据:
     function handler(event) {
       alert(event.data.foo);
     }
     $("p").bind("click", {foo: "bar"}, handler)
      
     //通过返回false来取消默认的行为并阻止事件起泡:
     $("form").bind("submit", function() { return false; })
      
     //通过使用 preventDefault() 方法只取消默认的行为:
     $("form").bind("submit", function(event){
       event.preventDefault();
     });
      
     //通过使用 stopPropagation() 方法只阻止一个事件起泡:
     $("form").bind("submit", function(event){
       event.stopPropagation();
     });
    
  2. underscore.js的apply方法

    apply主要作用是让我们可以控制方法中this指代的值,下面用代码表述:

     var func = function beautiful(){
       alert(this + ' is beautiful');
     };
     func.apply('Internet');
     //输出Internet is beautiful
    

    以上例子只帮我们理解apply的作用,实际上,apply的意义何在,请看下例:

     function Developer(skill) {
       this.skill = skill;
       this.says = function(){
         alert(this.skill + ' rocks!');
       }
     }
     var john = new Developer('Ruby');
     var func = john.says;
     func();
     //输出undefined rocks!
    

    上例可看出,在给调用对象john中的says方法定义一个单独的方法func后,执行func,this将被认为是func所处的对象,而不是john。这时apply可以解决问题,代码如下:

     function Developer(skill) {
       this.skill = skill;
       this.says = function(){
         alert(this.skill + ' rocks!');
       }
     }
     var john = new Developer('Ruby');
     var func = john.says;
     func.apply(john);
     //输出Ruby rocks!
    

    这样做太复杂,所以需要用bind和bindAll来简化和规范化,请往下看。

  3. underscore.js的bind方法

     function Developer(skill) {
       this.skill = skill;
       this.says = function(){
         alert(this.skill + ' rocks!');
       }
     }
     var john = new Developer('Ruby');
     var func = _.bind(john.says, john); //绑定的方法是john对象执行says方法,里面的this指代的是第二个参数john
     func();
     //输出Ruby rocks!
    

    注意:_.bind()返回的值才是绑定的方法,而不会影响里面绑定的方法本身,看下例:

     window.ProductView = Backbone.View.extrend({
       initialize: function() {
         _.bind(this.render, this);
         this.model.bind('change', this.render);
       }
     });
     //这样做的结果是change触发的是原this.render,方法中的this依然是不可性预计
      
      
     window.ProductView = Backbone.View.extrend({
       initialize: function() {
         var f_render=_.bind(this.render, this);
         this.model.bind('change', f_render);
       }
     });
     //这是正确做法,或者更直接简单:
      
     window.ProductView = Backbone.View.extrend({
       initialize: function() {
         this.model.bind('change', _.bind(this.render, this));
       }
     });
      
     //最简单当然是用_.bindAll:
     window.ProductView = Backbone.View.extrend({
       initialize: function() {
         _.bindAll(this, this.render);
         this.model.bind('change', this.render);
       }
     });
    
  4. underscore.js的bindAll方法

     function Developer(skill) {
       this.skill = skill;
       this.says = function(){
         alert(this.skill + ' rocks!');
       }
     }
     var john = new Developer('Ruby');
     _.bindAll(john, 'says'); //绑定的方法是john中的says方法,里面的this指代john
                              //可以一次过指定this到多个方法:_.bindAll(john,'says','work','gohome');
     var func = john.says;
     func();
     //输出Ruby rocks!
    

参考:http://blog.bigbinary.com/2011/08/18/understanding-bind-and-bindall-in-backbone.html

若您觉得我的博文对您有帮助,欢迎点击下方按钮对我打赏
打赏