JavaScript基础系列 —— 链式调用

遥记得,当年还没出山之前,最最开始的面试,人家问我:你觉得jQuery最好用、最厉害的地方是什么?

我说:链式调用

233333,当然现在觉得这个回答很搞笑。但是就当时而言,认为链式调用是多么神奇的一件事情。直到看了《JavaScript语言精粹》,才发现是这么的简单。

基础链式调用

1
[3, 2, 1].map(function (v) {
    return v * 2;
}).reverse()
.reduce(function (pre, cur, curIndex, arr) {
    console.log(pre, cur, curIndex, arr);
    return pre + cur;
});

'dfgkig'.split('').sort().join('');

jquery 链式调用

1
var random = function (num) {
    return Math.random() * num;
};

$.fn.test = function () {
    return this.each(function (index, value) {
        console.log('in each');
        if (index > 2) {
            return false;
        }
        $(this)
            .css({
                position: 'absolute',
                width: 100,
                height: 100,
                left: random(500),
                right: random(500)
            });
    });
};

// 例子
$('img').test().css('background', 'red').animate({
    opacity: 0
}, 5000);

underscore 链式调用

1
var _ = function(obj) {
    if (obj instanceof _) return obj;
    if (!(this instanceof _)) return new _(obj);
    // 把obj挂载到了 underscore 实例的 _wrapped 属性上
    this._wrapped = obj;
};
_.chain = function(obj) {
    var instance = _(obj);
    instance._chain = true;
    return instance;
};
var result = function(instance, obj) {
    return instance._chain ? _(obj).chain() : obj;
};
_.mixin = function(obj) {
    _.each(_.functions(obj), function(name) {
        var func = _[name] = obj[name];
        // 给 _ 的原型上,放置了 静态方法同名的方法
        _.prototype[name] = function() {
            // 拿到原来的obj对象
            var args = [this._wrapped];
            push.apply(args, arguments);
            return result(this, func.apply(_, args));
        };
    });
};

_.mixin(_);

// 例子
var stooges = [{name: 'curly', age: 25}, {name: 'moe', age: 21}, {name: 'larry', age: 23}];
var youngest = _.chain(stooges)
  .sortBy(function(stooge){ return stooge.age; })
  .map(function(stooge){ return stooge.name + ' is ' + stooge.age; })
  .first()
  .value();