Backbone中bind和bindAll用法和区别

Backbone中bind和bindAll用法和区别

1.概述

bindAll内部调用了bind(),而bind()又内部调用了apply()

2.详细介绍(由浅入深,请耐心看完)

(1)apply()的作用

apply lets us control the value of this when the function is invoked.

apply可以改变函数function的上下文,也就是this的值

例如:

var func = function beautiful(){
 alert(this + ' is beautiful'); //这里的this是全局变量 window
};
func();
var func = function beautiful(){
  alert(this + ' is beautiful');
};
func.apply('Internet');// 修改this的值

为什么要改变this的值?
举个例子:

function Developer(skill) {
  this.skill = skill;
  this.says = function(){
    alert(this.skill + ' rocks!');
  }
}
var john = new Developer('Ruby'); //实例化一个Developer
john.says(); //调用says()方法 Ruby rocks!

在这种情况下 this是Developer对象。
但是,如果换下面的写法,就不是了。

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!

在这种情况下,func()是在全局上下文调用的,所以this就变成了全局变量window,window.skill因为没有定义,所以是undefined。

我们使用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);

这种方式虽然解决了问题,但是每次调用时,都要传递“john”这个参数,不方便函数的调用。
因此,我们需要使用bind。

(2)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); //bind有返回值,返回一个函数
func();// Ruby rocks!

在这里我们来看一下bind的内部实现:

return function() {
  return func.apply(obj, args.concat(slice.call(arguments)));
};

我们可以看到bind的用法:
bind(方法名, this上下文)
但是,bind并没有修改原来的方法,而是返回一个新方法,这个新方法的this已经变成了第二个参数中赋予的值。

3.bindAll的使用

例如:

function Developer(skill) {
  this.skill = skill;
  this.says = function(){
    alert(this.skill + ' rocks!');
  }
}
var john = new Developer('Ruby');
_.bindAll(john, 'says');
var func = john.says;
func();

这是因为:
在使用bind时,必须使用bind返回的函数。
在使用bindAll时,不必考虑返回值。实质上,bindAll是改变了原来定义的函数。
在原来定义的Developer类中,有一个’says’属性,bindAll直接改变了’says’属性。

4.强调

我们在使用bind方法时经常会犯这种错误,例如:

window.ProductView = Backbone.View.extend({
  initialize: function() {
    _.bind(this.render, this);
    this.model.bind('change', this.render);
  }
});

这是因为bind的返回值没有被使用,所以_.bind(this.render, this);没有起作用。
修改方法:

window.ProductView = Backbone.View.extend({
  initialize: function() {
    var func = _.bind(this.render, this);
    this.model.bind('change', func);
    //或者
    // this.model.bind('change', _.bind(this.render, this));
  }
});

或者我们也可以使用bindAll

window.ProductView = Backbone.View.extend({
  initialize: function() {
    _.bindAll(this, this.render);
    this.model.bind('change', this.render);
  }
});

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值