V-1.8.2 underscore源码解析(二)
if(typeof exports !== "undefined") {
if(typeof module !== "undefined" && module.exports) {
exports = module.exports = _;
}
exports._ = _;
} else {
root._ = _;
}
将上面定义的 _
局部变量赋值给全局对象中的 _
属性
即客户端中 window._ = _
服务端(node)中 exports._ = _
在node.js上和浏览器用户端上 _ 是一个全局变量
_.VERSION = "1.8.2";
当前的版本
var optimizeCb = function(func, context, argCount) {
// 如无this指向,则返回原函数
if(context === void 0) return func;
switch(argCount == null ? 3 : argCount) {
case 1:
return function(value) {
return func.call(context, value);
};
case 2:
return function(value, other) {
return func.call(context, value);
};
case 3:
return function(value, index, collection) {
return func.call(context, value, index, collection);
};
case 4:
return function(value) {
return func.call(context, value, index, collection);
};
}
return function() {
return func.apply(context, arguments);
};
};
void 运算符能对给定的表达式进行求值,然后返回 undefined而且能节省字节,不少js工具在压缩过程中,正是用void 0 代替undefined。
对回调函数的优化,主要用来改变函数的执行环境和执行函数,对不同的参数个数做不同的处理,优化js引擎,避免使用arguments
使用call和apply函数来绑定执行上下文。
根据是否有参数和参数的不同类型,返回不同的函数或值
var cb = function(value, context, argCount) {
// 根据不同的value属性,返回调用不同的函数
if(value == null) return _.identity;
if(_.isFunction(value)) return optimizeCb(value, context, argCount);
if(_.isObject(value)) return _.matcher(value);
return _.property(value);
};
_.iteratee = function(value, context) {
return cb(value, context, Infinity);
};
var createAssigner = function(keysFunc, undefinedOnly) {
return function(obj) {
var length = arguments.length;
// 当返回的函数参数的个数为0或者1或者为null的时候
if(length < 2 || obj == null) return obj;
// 当返回的函数参数个数大于1的时候
for(var index = 1; index < length; index++) {
// var一个变量source接收arguments[1],source为对象参数;
var source = arguments[index],
// 将第二个开始的对象参数的键值对作为参数传入第一个参数函数
// 返回一个数组
keys = keysFunc(source),
l = keys.length;
for(var i = 0; i < l; i++) {
var key = keys[i];
// 当obj[key]为undefined的时候才覆盖,即如果有相同的key值,则
// 取首次出现的value值
if(!undefinedOnly || obj[key] === void 0)
obj[key] = source[key];
}
}
return obj;
};
};
// An internal function for creating a new object that inherits from another.
// 创建一个继承自另外一个对象的新对象,原型继承
var baseCreate = function(prototype) {
// 如果prototype不是一个对象,返回一个新对象
if(!_.isObject(prototype)) return {};
// es5的一种新的对象创建方式,如果浏览器支持这个属性,则执行这一步,创建一个新对象
if(nativeCreate) return nativeCreate(prototype);
Ctor.prototype = prototype;
var result = new Ctor;
Ctor.prototype = null;
return result;
// 返回一个函数实例
};
var property = function(key) {
return function(obj) {
return obj == null ? void 0 : obj[key];
};
};
// 闭包
// 返回一个函数,如果obj是null或者undefined,返回undefined,否则返回obj[key]即
// key对象对应的属性值
var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;
// 返回2的53次幂-1
var isArrayLike = function(collection) {
var length = collection != null && collection.length;
// 获取参数的长度,判断类数组拥有length属性,并且限定长度区间
return typeof length == "number" && length >= 0 && length <= MAX_ARRAY_INDEX;
// 利用短路优化性能,返回length的类型为数字,长度在0-2^53-1之间
};
// isArrayLike判 断collection是否是一个类数组或者对象
// Helper for collection methods to determine whether a collection
// should be iterated as an array or as an object
// Math.pow(2, 53) - 1 是 JavaScript 中能精确表示的最大数字