首页 > 其他 > 详细

理解并实现 underscore 中的 bind 和 bindAll 函数

时间:2015-08-14 13:55:15      阅读:197      评论:0      收藏:0      [点我收藏+]

在开始之前,我们定义了 Person 类:

function Person(name) { this.name = name;
}
Person.prototype.say = function() {
    console.log(this.name);
}

首先,新建 person 对象:

var wenyi = new Person(‘wenyi‘);
wenyi.say(); // wenyi

可以看到这里输出的结果是 wenyi,没什么好说的,因为这里的 this 指向的是 wenyi 这个对象。

接下来,我将 say 函数赋值给一个变量,会怎么样呢?

var func = wenyi.say;
func(); // 空

可以看到输出的结果为空,因为赋值给 func 后,这里的 this 指向的是 window,而 window.name 为空。

为了改变 this 的指向,我们可以使用 apply 方法:

func.apply(wenyi); // wenyi

在实际的使用中,我们常常看到这样的代码:

$(‘button‘).click(function() {
    wenyi.say();
});
  • 它并不美观,因为还得嵌套多一层 function 来解决 this 的指向问题
  • 像上面将 say 函数赋值给 func 变量后,转移的责任者并不能正确的使用原来的函数

而使用 bind 和 bindAll 函数可以很好的解决上面的问题:

var func = bind(wenyi, wenyi.say);
func(); // wenyi

bindAll(wenyi, ‘say‘);
var func = wenyi.say;
func(); // wenyi



那么,要怎么实现 bind 和 bindAll 函数呢?

function bind(obj, func) {
    return function() {
        return func.apply(obj, Array.prototype.slice.call(arguments));
    };
}
function bindAll(obj) {
    var funcs = Array.prototype.slice.call(arguments, 1);
    for (var i = 0; i < funcs.length; i++) {
        obj[funcs[i]] = bind(obj, obj[funcs[i]]);
    }
    return obj;
}
  • bind 的实现就是通过 apply 方法
  • bindAll 的实现是利用 bind 将所有方法重新赋值

最后,附上一个实际使用到完整的例子

function Person(name, age) {
    this.name = name;
    this.age = age;

    bindAll(this, ‘sayName‘, ‘sayAge‘);
}
Person.prototype.sayName = function() {
    console.log(this.name);
}
Person.prototype.sayAge = function() {
    console.log(this.age);
}

var wenyi = new Person(‘wenyi‘, 26);

var func = wenyi.sayName;
func(); // wenyi

$(‘button‘).click(wenyi.sayAge); // 26




注:
以上为个人的理解,如有不准确的地方,欢迎有相关研究的同行指正。
完整的实现请查看 underscore 的源码。

理解并实现 underscore 中的 bind 和 bindAll 函数

原文:http://my.oschina.net/uniquejava/blog/492294

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!