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

在开始之前,我们定义了 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 的源码。

时间: 2024-10-16 19:58:52

理解并实现 underscore 中的 bind 和 bindAll 函数的相关文章

理解 Backbone.js中的bind和bindAll

http://blog.bigbinary.com/2011/08/18/understanding-bind-and-bindall-in-backbone.html http://wenzhixin.net.cn/2013/11/01/understanding_bind_bindall http://chaoskeh.com/blog/use-underscore-bindall-carefully.html

必须正确理解的---ng指令中的compile与link函数解析

这个绝对是深入的知识,但看完之后,对NG的理解就很利害啦. http://www.ifeenan.com/angularjs/2014-09-04-%5B%E8%AF%91%5DNG%E6%8C%87%E4%BB%A4%E4%B8%AD%E7%9A%84compile%E4%B8%8Elink%E5%87%BD%E6%95%B0%E8%A7%A3%E6%9E%90/ 开始分析之前,先让我们看看ng中是怎么样处理指令的. 当浏览器渲染一个页面时,本质上是读html标识,然后建立dom节点,当dom

underscore中的几个功能函数

今天看了下书,写了几个underscore下的几个功能方法 1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 5 <title>无标题文档</title> 6 <script type="text/javascript&

理解Underscore中的_.template函数

Underscore中提供了_.template函数实现模板引擎功能,它可以将JSON数据源中的数据对应的填充到提供的字符串中去,类似于服务端渲染的模板引擎.接下来看一下Underscore是如何实现模板引擎的. 工具准备 首先是_.template函数的配置项,Underscore源码中配置了默认的配置项: _.templateSettings = { // 执行JavaScript语句,并将结果插入. evaluate: /<%([\s\S]+?)%>/g, // 插入变量的值. inte

理解ruby on rails中的ActiveRecord::Relation

ActiveRecord::Relation是rails3中添加的.rails2中的finders, named_scope, with_scope 等用法,在rails3统一为一种Relation用法. 以下是返回ActiveRecord::Relation的方法: bind create_with distinct eager_load extending from group having includes joins limit lock none offset order preloa

译:理解并掌握 JavaScript 中 this 的用法

原文链接:http://javascriptissexy.com/understand-javascripts-this-with-clarity-and-master-it/ 文章描述:本文原文来自 Javascript.isSexy 这个网站.这篇文章和文中提到的另一篇文章解决了我一直以来对 this 和 apply, call, bind 这三个方法的困惑.我看过很多国内相关的技术文章,没有一篇能让我彻底理解这些概念的.因此我决定把它译过来,不要让更多的初学者像我一样在这个问题上纠结太长时

【转载】JS中bind方法与函数柯里化

原生bind方法 不同于jQuery中的bind方法只是简单的绑定事件函数,原生js中bind()方法略复杂,该方法上在ES5中被引入,大概就是IE9+等现代浏览器都支持了(有关ES5各项特性的支持情况戳这里ECMAScript 5 compatibility table),权威指南上提到在ES3中利用apply模拟该方法的实现(JS权威指南中函数那章), 但无法真实还原该方法, 这也是真bind方法中的有趣特性. (原文这边理解有问题, 这段话的意思如果结合犀牛书上下文的意思, 再结合犀牛书中

理解并掌握 JavaScript 中 this 的用法[转]

本文原文来自 Javascript.isSexy 这个网站 来源:code.mforever78.com JavaScript this 用法基础 理解 JavaScript this 的关键 在全局作用域中使用 this this 最容易被误解和难以掌握的情景 1. 解决当包含 this 的方法被当做回调函数时遇到的问题 2. 解决当 this 出现在闭包内遇到的问题 3. 解决把一个 this 方法 赋给一个变量时出现的问题 4. 解决当借用方法的时候 this 的值不正确的问题 结语 我们

JavaScript中的bind,call和apply函数的用法和区别

一直没怎么使用过JavaScript中的bind,call和apply, 今天看到一篇比较好的文章,觉得讲的比较透彻,所以记录和总结如下 首先要理解的第一个概念,JavaScript中函数调用的方式,总结下来,有以下4种 1. 方法调用 2. 正常函数调用 3. 构造器函数调用 4. apply/call 调用 要明白的第2个概念, JavaScript 中的函数,无论是上面哪种函数调用方式,除了你函数声明时定义的形参外,还会自动给函数添加两个形参,分别是this 和 arguments 要明白