underscore.js 剩余部分2 --- 面向对象及链式调用

_.mixin

 // Add your own custom functions to the Underscore object.
  _.mixin = function(obj) {
    _.each(_.functions(obj), function(name) {
      var func = _[name] = obj[name];
      _.prototype[name] = function() {
        var args = [this._wrapped];
        push.apply(args, arguments);
        return chainResult(this, func.apply(_, args));
      };
    });
    return _;
  };

  // Add all of the Underscore functions to the wrapper object.
  _.mixin(_);

我们看到,之前我们所定义的underscore属性都是直接定义,属于静态,然而我们没有办法将这些属性让实例继承,于是怎么办?underscore中通过这个mixin函数解决了一切。

.each 加上 .functions获取方法

我们看到内部:

_.each(_.functions(obj), function(name) {
      var func = _[name] = obj[name];

首先就是将underscore中的所有方法进行遍历放入数组,用_.each进行遍历。func变量保存当前拿到的方法。

underscore的面向对象处理

我们知道,当我们_(ele)
之后,再调用underscore的方法时,就可以省去第一个变量的输入,即target object,这又是怎么做到的?

回到underscore最初的定义方式

// Create a safe reference to the Underscore object for use below.
  var _ = function(obj) {
    if (obj instanceof _) return obj;
    if (!(this instanceof _)) return new _(obj);
    this._wrapped = obj;
  };

我们看到,当我们输入一个obj给underscore时,首先underscore函数内部会对obj进行判断,如果传入的是underscore的实例,则返回传入的underscore,如果不是,则new一个新的underscore对象出来,并且含有一个_.wrapped属性,包含我们想要处理的target object。

underscore的prototype方法定义

那么underscore是如何给之后的方法传入_.wrapped中的值呢?

 _.prototype[name] = function() {
        var args = [this._wrapped]; // 
        push.apply(args, arguments);
        return chainResult(this, func.apply(_, args));
      };

我们看到,每个prototype中的方法都变成了一个调用函数,用来将wrapped变为第一个参数传入,而将其他argments放入args的剩余属性中,再将之传入chainResult内,同时调用

chainResult

我们看chainResult函数

var chainResult = function(instance, obj) {
    return instance._chain ? _(obj).chain() : obj;
  };

chainResult判断instance是否含有_chain,有则调用chain()函数,没有则返回传入的对象

  // Add a "chain" function. Start chaining a wrapped Underscore object.
  _.chain = function(obj) {
    var instance = _(obj);
    instance._chain = true;
    return instance;
  };

很明显,我们每次一用chain,就会产生一个新的underscore对象,chain属性为true,.wrapped为我们之前用方法处理得到的值。

比如:


_([1,2,3,4,5]).chain().map(function () {
    return 1 // 将原本元素变为1
}).each(function (item) {
    console.log(item) // 1 1 1 1 1
})

大致就是这么操作的

还有一个noConflict

_.noConflict = function() {
    root._ = previousUnderscore;
    return this;
  };

应该不必多说了

没了

这里写图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值