没有合适的资源?快使用搜索试试~ 我知道了~
Underscore.js 1.3.3 中文注释翻译说明
1 下载量 26 浏览量
2020-10-24
00:41:04
上传
评论
收藏 179KB PDF 举报
温馨提示
试读
21页
Underscore一个JavaScript实用库,提供了一整套函数式编程的实用功能,但是没有扩展任何JavaScript内置对象,本文就翻译了它的源代码中的注释,需要的朋友可以参考下
资源推荐
资源详情
资源评论
Underscore.js 1.3.3 中文注释翻译说明中文注释翻译说明
Underscore一个JavaScript实用库,提供了一整套函数式编程的实用功能,但是没有扩展任何JavaScript内置对象,本文就翻译了它的源代码中的注释,需要的朋友可以参考下
// Underscore.js 1.3.3
// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
// Underscore is freely distributable under the MIT license.
// Portions of Underscore are inspired or borrowed from Prototype,
// Oliver Steele's Functional, and John Resig's Micro-Templating.
// For all details and documentation:
// http://documentcloud.github.com/underscore
(function() {
// 创建一个全局对象, 在浏览器中表示为window对象, 在Node.js中表示global对象
var root = this;
// 保存"_"(下划线变量)被覆盖之前的值
// 如果出现命名冲突或考虑到规范, 可通过_.noConflict()方法恢复"_"被Underscore占用之前的值, 并返回Underscore对象以便重新命名
var previousUnderscore = root._;
// 创建一个空的对象常量, 便于内部共享使用
var breaker = {};
// 将内置对象的原型链缓存在局部变量, 方便快速调用
var ArrayProto = Array.prototype, //
ObjProto = Object.prototype, //
FuncProto = Function.prototype;
// 将内置对象原型中的常用方法缓存在局部变量, 方便快速调用
var slice = ArrayProto.slice, //
unshift = ArrayProto.unshift, //
toString = ObjProto.toString, //
hasOwnProperty = ObjProto.hasOwnProperty;
// 这里定义了一些JavaScript 1.6提供的新方法
// 如果宿主环境中支持这些方法则优先调用, 如果宿主环境中没有提供, 则会由Underscore实现
var nativeForEach = ArrayProto.forEach, //
nativeMap = ArrayProto.map, //
nativeReduce = ArrayProto.reduce, //
nativeReduceRight = ArrayProto.reduceRight, //
nativeFilter = ArrayProto.filter, //
nativeEvery = ArrayProto.every, //
nativeSome = ArrayProto.some, //
nativeIndexOf = ArrayProto.indexOf, //
nativeLastIndexOf = ArrayProto.lastIndexOf, //
nativeIsArray = Array.isArray, //
nativeKeys = Object.keys, //
nativeBind = FuncProto.bind;
// 创建对象式的调用方式, 将返回一个Underscore包装器, 包装器对象的原型中包含Underscore所有方法(类似与将DOM对象包装为一个jQuery对象)
var _ = function(obj) {
// 所有Underscore对象在内部均通过wrapper对象进行构造
return new wrapper(obj);
};
// 针对不同的宿主环境, 将Undersocre的命名变量存放到不同的对象中
if( typeof exports !== 'undefined') {// Node.js环境
if( typeof module !== 'undefined' && module.exports) {
exports = module.exports = _;
}
exports._ = _;
} else {// 浏览器环境中Underscore的命名变量被挂在window对象中
root['_'] = _;
}
// 版本声明
_.VERSION = '1.3.3';
// 集合相关的方法(数据和对象的通用处理方法)
// --------------------
// 迭代处理器, 对集合中每一个元素执行处理器方法
var each = _.each = _.forEach = function(obj, iterator, context) {
// 不处理空值
if(obj == null)
return;
if(nativeForEach && obj.forEach === nativeForEach) {
// 如果宿主环境支持, 则优先调用JavaScript 1.6提供的forEach方法
obj.forEach(iterator, context);
} else if(obj.length === +obj.length) {
// 对<数组>中每一个元素执行处理器方法
for(var i = 0, l = obj.length; i < l; i++) {
if( i in obj && iterator.call(context, obj[i], i, obj) === breaker)
return;
}
} else {
// 对<对象>中每一个元素执行处理器方法
for(var key in obj) {
if(_.has(obj, key)) {
if(iterator.call(context, obj[key], key, obj) === breaker)
return;
}
}
}
};
// 迭代处理器, 与each方法的差异在于map会存储每次迭代的返回值, 并作为一个新的数组返回
_.map = _.collect = function(obj, iterator, context) {
// 用于存放返回值的数组
var results = [];
if(obj == null)
return results;
// 优先调用宿主环境提供的map方法
if(nativeMap && obj.map === nativeMap)
return obj.map(iterator, context);
// 迭代处理集合中的元素
each(obj, function(value, index, list) {
// 将每次迭代处理的返回值存储到results数组
results[results.length] = iterator.call(context, value, index, list);
});
// 返回处理结果
if(obj.length === +obj.length)
results.length = obj.length;
return results;
};
// 将集合中每个元素放入迭代处理器, 并将本次迭代的返回值作为"memo"传递到下一次迭代, 一般用于累计结果或连接数据
_.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
// 通过参数数量检查是否存在初始值
var initial = arguments.length > 2;
if(obj == null)
obj = [];
// 优先调用宿主环境提供的reduce方法
if(nativeReduce && obj.reduce === nativeReduce && false) {
if(context)
iterator = _.bind(iterator, context);
return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
}
// 迭代处理集合中的元素
each(obj, function(value, index, list) {
if(!initial) {
// 如果没有初始值, 则将第一个元素作为初始值; 如果被处理的是对象集合, 则默认值为第一个属性的值
memo = value;
initial = true;
} else {
// 记录处理结果, 并将结果传递给下一次迭代
memo = iterator.call(context, memo, value, index, list);
}
});
if(!initial)
throw new TypeError('Reduce of empty array with no initial value');
return memo;
};
// 与reduce作用相似, 将逆向迭代集合中的元素(即从最后一个元素开始直到第一个元素)
_.reduceRight = _.foldr = function(obj, iterator, memo, context) {
var initial = arguments.length > 2;
if(obj == null)
obj = [];
// 优先调用宿主环境提供的reduceRight方法
if(nativeReduceRight && obj.reduceRight === nativeReduceRight) {
if(context)
iterator = _.bind(iterator, context);
return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
}
// 逆转集合中的元素顺序
var reversed = _.toArray(obj).reverse();
if(context && !initial)
iterator = _.bind(iterator, context);
// 通过reduce方法处理数据
return initial ? _.reduce(reversed, iterator, memo, context) : _.reduce(reversed, iterator);
};
// 遍历集合中的元素, 返回第一个能够通过处理器验证的元素
_.find = _.detect = function(obj, iterator, context) {
// result存放第一个能够通过验证的元素
var result;
// 通过any方法遍历数据, 并记录通过验证的元素
// (如果是在迭代中检查处理器返回状态, 这里使用each方法会更合适)
any(obj, function(value, index, list) {
// 如果处理器返回的结果被转换为Boolean类型后值为true, 则当前记录并返回当前元素
if(iterator.call(context, value, index, list)) {
result = value;
return true;
}
});
return result;
};
// 与find方法作用类似, 但filter方法会记录下集合中所有通过验证的元素
_.filter = _.select = function(obj, iterator, context) {
// 用于存储通过验证的元素数组
var results = [];
if(obj == null)
return results;
// 优先调用宿主环境提供的filter方法
if(nativeFilter && obj.filter === nativeFilter)
return obj.filter(iterator, context);
// 迭代集合中的元素, 并将通过处理器验证的元素放到数组中并返回
each(obj, function(value, index, list) {
if(iterator.call(context, value, index, list))
results[results.length] = value;
});
return results;
};
// 与filter方法作用相反, 即返回没有通过处理器验证的元素列表
_.reject = function(obj, iterator, context) {
var results = [];
if(obj == null)
return results;
each(obj, function(value, index, list) {
if(!iterator.call(context, value, index, list))
results[results.length] = value;
});
return results;
};
// 如果集合中所有元素均能通过处理器验证, 则返回true
_.every = _.all = function(obj, iterator, context) {
var result = true;
if(obj == null)
return result;
// 优先调用宿主环境提供的every方法
if(nativeEvery && obj.every === nativeEvery)
return obj.every(iterator, context);
// 迭代集合中的元素
each(obj, function(value, index, list) {
// 这里理解为 result = (result && iterator.call(context, value, index, list))
// 验证处理器的结果被转换为Boolean类型后是否为true值
if(!( result = result && iterator.call(context, value, index, list)))
return breaker;
});
return !!result;
};
// 检查集合中任何一个元素在被转换为Boolean类型时, 是否为true值?或者通过处理器处理后, 是否值为true?
var any = _.some = _.any = function(obj, iterator, context) {
// 如果没有指定处理器参数, 则默认的处理器函数会返回元素本身, 并在迭代时通过将元素转换为Boolean类型来判断是否为true值
iterator || ( iterator = _.identity);
var result = false;
if(obj == null)
return result;
// 优先调用宿主环境提供的some方法
if(nativeSome && obj.some === nativeSome)
return obj.some(iterator, context);
// 迭代集合中的元素
each(obj, function(value, index, list) {
if(result || ( result = iterator.call(context, value, index, list)))
return breaker;
});
return !!result;
};
// 检查集合中是否有值与目标参数完全匹配(同时将匹配数据类型)
_.include = _.contains = function(obj, target) {
var found = false;
if(obj == null)
return found;
// 优先调用宿主环境提供的Array.prototype.indexOf方法
if(nativeIndexOf && obj.indexOf === nativeIndexOf)
return obj.indexOf(target) != -1;
// 通过any方法迭代集合中的元素, 验证元素的值和类型与目标是否完全匹配
found = any(obj, function(value) {
return value === target;
});
return found;
};
// 依次调用集合中所有元素的同名方法, 从第3个参数开始, 将被以此传入到元素的调用方法中
// 返回一个数组, 存储了所有方法的处理结果
_.invoke = function(obj, method) {
// 调用同名方法时传递的参数(从第3个参数开始)
var args = slice.call(arguments, 2);
// 依次调用每个元素的方法, 并将结果放入数组中返回
return _.map(obj, function(value) {
return (_.isFunction(method) ? method || value : value[method]).apply(value, args);
});
};
// 遍历一个由对象列表组成的数组, 并返回每个对象中的指定属性的值列表
_.pluck = function(obj, key) {
// 如果某一个对象中不存在该属性, 则返回undefined
return _.map(obj, function(value) {
return value[key];
});
};
// 返回集合中的最大值, 如果不存在可比较的值, 则返回undefined
_.max = function(obj, iterator, context) {
// 如果集合是一个数组, 且没有使用处理器, 则使用Math.max获取最大值
// 一般会是在一个数组存储了一系列Number类型的数据
if(!iterator && _.isArray(obj) && obj[0] === +obj[0])
return Math.max.apply(Math, obj);
// 对于空值, 直接返回负无穷大
if(!iterator && _.isEmpty(obj))
return -Infinity;
// 一个临时的对象, computed用于在比较过程中存储最大值(临时的)
var result = {
computed : -Infinity
};
// 迭代集合中的元素
each(obj, function(value, index, list) {
// 如果指定了处理器参数, 则比较的数据为处理器返回的值, 否则直接使用each遍历时的默认值
var computed = iterator ? iterator.call(context, value, index, list) : value;
// 如果比较值相比上一个值要大, 则将当前值放入result.value
computed >= result.computed && ( result = {
value : value,
computed : computed
});
});
// 返回最大值
return result.value;
};
// 返回集合中的最小值, 处理过程与max方法一致
_.min = function(obj, iterator, context) {
if(!iterator && _.isArray(obj) && obj[0] === +obj[0])
return Math.min.apply(Math, obj);
if(!iterator && _.isEmpty(obj))
return Infinity;
var result = {
computed : Infinity
};
each(obj, function(value, index, list) {
var computed = iterator ? iterator.call(context, value, index, list) : value;
computed < result.computed && ( result = {
value : value,
computed : computed
});
});
return result.value;
};
// 通过随机数, 让数组无须排列
_.shuffle = function(obj) {
// shuffled变量存储处理过程及最终的结果数据
var shuffled = [], rand;
// 迭代集合中的元素
each(obj, function(value, index, list) {
// 生成一个随机数, 随机数在<0-当前已处理的数量>之间
rand = Math.floor(Math.random() * (index + 1));
// 将已经随机得到的元素放到shuffled数组末尾
shuffled[index] = shuffled[rand];
// 在前面得到的随机数的位置插入最新值
shuffled[rand] = value;
});
// 返回一个数组, 该数组中存储了经过随机混排的集合元素
return shuffled;
};
// 对集合中元素, 按照特定的字段或值进行排列
剩余20页未读,继续阅读
资源评论
weixin_38516190
- 粉丝: 8
- 资源: 896
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功