_.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;
};
应该不必多说了
没了