热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

underscore.js源码进修collection

Internalfunctionthatreturnsanefficient(forcurrentengines)versionofthepassed-incallback,tob

// Internal function that returns an efficient (for current engines) version
// of the passed-in callback, to be repeatedly applied in other Underscore
// functions.
// 内部复用函数,用于转变函数上下文。

var optimizeCb = function(func, context, argCount) {
//context为undefined状况下,直接返回func
// void 0
// 实行历程:1,对右边表达式求值。2.返回undefined
// 为什么如许节外生枝:js中,undefined不是保留字,能够建立windows.undefined=anything.void返回undefined较平安。
// 用途:1返回undefined。2a标签不跳转href=Javascript:(void 0)3img空图片src=Javascript:(void 0)
if (cOntext=== void 0) return func;
//有传入context状况下,将func上下文改成context
switch (argCount == null ? 3 : argCount) {
case 1:
return function(value) {
return func.call(context, value);
};
// The 2-argument case is omitted because we’re not using it.
case 3:
return function(value, index, collection) {
return func.call(context, value, index, collection);
};
//_.reduce中运用
case 4:
return function(accumulator, value, index, collection) {
return func.call(context, accumulator, value, index, collection);
};
}
return function() {
return func.apply(context, arguments);
};
};
var builtinIteratee;

// An internal function to generate callbacks that can be applied to each
// element in a collection, returning the desired result — either identity,
// an arbitrary callback, a property matcher, or a property accessor.
// 内部函数,天生适用于鸠合每一个元素的回调函数
// 传入null等空值,获得等价函数
// 传入function,获得绑定了上下文的函数
// 传入对象,获得婚配函数
// 传入其他,获得属性接见函数

var cb = function(value, context, argCount) {
//??是何意图??
if (_.iteratee !== builtinIteratee) return _.iteratee(value, context);
//返回null
if (value == null) return _.identity;
//假如是函数,绑定函数上下文
if (_.isFunction(value)) return optimizeCb(value, context, argCount);
//假如是对象,返回婚配函数
if (_.isObject(value) && !_.isArray(value)) return _.matcher(value);
//返回猎取属性值函数
return _.property(value);
};

// External wrapper for our callback generator. Users may customize
// _.iteratee if they want additional predicate/iteratee shorthand styles.
// This abstraction hides the internal-only argCount argument.
// 外部函数,返回cb函数效果

_.iteratee = builtinIteratee = function(value, context) {
return cb(value, context, Infinity);
};

// Some functions take a variable number of arguments, or a few expected
// arguments at the beginning and then a variable number of values to operate
// on. This helper accumulates all remaining arguments past the function’s
// argument length (or an explicit startIndex), into an array that becomes
// the last argument. Similar to ES6’s “rest parameter”.
// 用于实参个数不定的函数的牢固参数及盈余参数整顿。
// example:_.invoke
// func.length=3,so startIndex=2,即从第三个参数最先,都存入rest变量中,并作为第三个参数传入。第一二个参数稳固。
// example:_.without
// func.length=2,so startIndex=1,即从第二个参数最先,都存入rest变量中,并作为第二个参数传入第一个参数稳固。
// example:_.union
// func.length=1,so startIndex=0,行将一切参数都传入rest变量中,并作为第一个参数传入。
// 末了一种状况,func形参个数大于3,不再运用call手动传入参数
// 而是应用apply的数组参数特征,将参数保留在数组中,再传入函数。

var restArguments = function(func, startIndex) {
console.log('func2')
//func.length->形参个数
startIndex = startIndex == null ? func.length - 1 : +startIndex;
return function() { //func3
// arguments.length->实参个数
// 个人明白:此处arguments指的是最切近的这个闭包function在实行时传入的参数,并非func在实行时传入的参数个数。
console.log('func3')
var length = Math.max(arguments.length - startIndex, 0),
rest = Array(length),
index = 0;
for (; index rest[index] = arguments[index + startIndex];
}
switch (startIndex) {
case 0:
return func.call(this, rest);
case 1:
return func.call(this, arguments[0], rest);
case 2:
return func.call(this, arguments[0], arguments[1], rest);
}
var args = Array(startIndex + 1);
for (index = 0; index args[index] = arguments[index];
}
args[startIndex] = rest;
return func.apply(this, args);
};
};

// Invoke a method (with arguments) on every item in a collection.
// 在鸠合的每一个元素上挪用要领path,参数为arguments
// _.invoke([[3,4,5],[65,33,3]],’sort’)函数运转递次
// 在underscore.js加载编译时,restArgument被实行,console func2。并返回匿名函数func3
// 在_.invoke()被实行,即匿名函数func3被实行,console func3。此时的arguments=[[[3,4,5],[65,33,3]],’sort’]。返回匿名函数func实行的值
// 实行func,console func。参数obj = arguments[0]=[[[3,4,5],[65,33,3]],path = arguemnts[1]=’sort’,args = rest = []
// console func4
// console func4

_.invoke = restArguments(function(obj, path, args) { //func
console.log('func')
var contextPath, func;
if (_.isFunction(path)) {
func = path;
} else if (_.isArray(path)) {
cOntextPath= path.slice(0, -1);
path = path[path.length - 1];
}
return _.map(obj, function(context) { //func4
console.log('func4')
var method = func;
if (!method) {
if (contextPath && contextPath.length) {
cOntext= deepGet(context, contextPath);
}
if (cOntext== null) return void 0;
method = context[path];
}
return method == null ? method : method.apply(context, args);
});
});

// An internal function for creating a new object that inherits from another.

var baseCreate = function(prototype) {
if (!_.isObject(prototype)) return {};
if (nativeCreate) return nativeCreate(prototype);
Ctor.prototype = prototype;
var result = new Ctor;
Ctor.prototype = null;
return result;
};

// 偏函数与柯里函数区分
// 偏函数:传入某些牢固参数后,返回包括牢固参数,并可传入其他参数的函数
// 柯里函数:将n元参数的函数转变成n次函数,每次都只能传入一个参数。
// 接见属性函数

var shallowProperty = function(key) {
return function(obj) {
return obj == null ? void 0 : obj[key];
};
};

//推断是不是存在自有属性path

var has = function(obj, path) {
return obj != null && hasOwnProperty.call(obj, path);
}

//接见对象的深度多级属性 函数

var deepGet = function(obj, path) {
var length = path.length;
for (var i = 0; i if (obj == null) return void 0;
obj = obj[path[i]];
}
return length ? obj : void 0;
};

// Helper for collection methods to determine whether a collection
// should be iterated as an array or as an object.
// Related: http://people.mozilla.org/~jo…
// Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094
// js 最大的准确整数值

var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;
var getLength = shallowProperty('length');
var isArrayLike = function(collection) {
var length = getLength(collection);
return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX;
};

// Collection Functions
// &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;
// The cornerstone, an each implementation, aka forEach.
// Handles raw objects in addition to array-likes. Treats all
// sparse array-likes as if they were dense.
// each与map区分
// each中iteratee函数实行效果不保留,返回obj自身
// map中iteratee函数实行效果保留到数组results中,并返回。

_.each = _.forEach = function(obj, iteratee, context) {
iteratee = optimizeCb(iteratee, context);
var i,
keys = !isArrayLike(obj) && _.keys(obj),
length = (keys || obj).length;
for (i = 0; i var currentKey = keys ? keys[i] : i;
iteratee(obj[currentKey], currentKey, obj);
}
return obj;
};

// Return the results of applying the iteratee to each element.

_.map = _.collect = function(obj, iteratee, context) {
//包装实行函数上下文
iteratee = cb(iteratee, context);
var keys = !isArrayLike(obj) && _.keys(obj),
length = (keys || obj).length,
results = Array(length);
for (var index = 0; index var currentKey = keys ? keys[index] : index;
results[index] = iteratee(obj[currentKey], currentKey, obj);
}
return results;
};

// Create a reducing function iterating left or right.
// 建立迭代函数,可选遍历方向

var createReduce = function(dir) {
// Wrap code that reassigns argument variables in a separate function than
// the one that accesses `arguments.length` to avoid a perf hit. (#1991)
// perf hit是performance hit的简写。
// arguments的运用,会致使一些机能题目。如chrome nodejs的v8引擎在运用arguments会代码优化步骤被跳过。
var reducer = function(obj, iteratee, memo, initial) { //func2
var keys = !isArrayLike(obj) && _.keys(obj),
length = (keys || obj).length,
index = dir > 0 ? 0 : length - 1;
if (!initial) {
memo = obj[keys ? keys[index] : index];
index += dir;
}
for (; index >= 0 && index var currentKey = keys ? keys[index] : index;
memo = iteratee(memo, obj[currentKey], currentKey, obj);
}
return memo;
};
// 此处返回func1函数,作用域中包括initial变量,存放了arguments.length,
// 意图就在于将arguments变量从reducer函数中分离出来,
// 并在挪用reducer函数时,开释argumenrs变量,防止机能题目。
return function(obj, iteratee, memo, context) { //func1
var initial = arguments.length >= 3;
return reducer(obj, optimizeCb(iteratee, context, 4), memo, initial);
};
};

// Reduce builds up a single result from a list of values, aka inject,
// or foldl.

_.reduce = _.foldl = _.inject = createReduce(1);

// The right-associative version of reduce, also known as foldr.

_.reduceRight = _.foldr = createReduce(-1);

// Return the first value which passes a truth test. Aliased as detect.
// 返回第一个断言问真的值

_.find = _.detect = function(obj, predicate, context) {
var keyFinder = isArrayLike(obj) ? _.findIndex : _.findKey;
var key = keyFinder(obj, predicate, context);
if (key !== void 0 && key !== -1) return obj[key];
};

// Return all the elements that pass a truth test.
// Aliased as select.
// 返回一切断言为真的值构成的数组,半途不中缀

_.filter = _.select = function(obj, predicate, context) {
var results = [];
predicate = cb(predicate, context);
_.each(obj, function(value, index, list) {
if (predicate(value, index, list)) results.push(value);
});
return results;
};

// Return all the elements for which a truth test fails.
// 返回一切断言为假的值,
// 内部直接挪用filter

_.reject = function(obj, predicate, context) {
return _.filter(obj, _.negate(cb(predicate)), context);
};

// Determine whether all of the elements match a truth test.
// Aliased as all.
// 推断是不是一切断言函数都为真,涌现假马上返回

_.every = _.all = function(obj, predicate, context) {
predicate = cb(predicate, context);
var keys = !isArrayLike(obj) && _.keys(obj),
length = (keys || obj).length;
for (var index = 0; index var currentKey = keys ? keys[index] : index;
if (!predicate(obj[currentKey], currentKey, obj)) return false;
}
return true;
};

// Determine if at least one element in the object matches a truth test.
// Aliased as any.
// 检测是不是至少有一个值断言为真,涌现真马上返回

_.some = _.any = function(obj, predicate, context) {
predicate = cb(predicate, context);
var keys = !isArrayLike(obj) && _.keys(obj),
length = (keys || obj).length;
for (var index = 0; index var currentKey = keys ? keys[index] : index;
if (predicate(obj[currentKey], currentKey, obj)) return true;
}
return false;
};

// Determine if the array or object contains a given item (using ===).
// Aliased as includes and include.
// 推断从fromIndex索引最先,是不是包括item

_.cOntains= _.includes = _.include = function(obj, item, fromIndex, guard) {
if (!isArrayLike(obj)) obj = _.values(obj);
if (typeof fromIndex != 'number' || guard) fromIndex = 0;
return _.indexOf(obj, item, fromIndex) >= 0;
};

// Convenience version of a common use case of map: fetching a property.
// 萃取数组对象中某属性值,返回一个数组

_.pluck = function(obj, key) {
return _.map(obj, _.property(key));
};

// Convenience version of a common use case of filter: selecting only objects
// containing specific key:value pairs.
// 遍历list中的每一个值,返回一个数组,这个数组里的元素包括 properties 所列出的键 &#8211; 值对。

_.where = function(obj, attrs) {
return _.filter(obj, _.matcher(attrs));
};

// Convenience version of a common use case of find: getting the first object
// containing specific key:value pairs.
// 遍历全部list,返回 matches(婚配) properties参数所列出的一切 键 &#8211; 值 对的第一个值。

_.findWhere = function(obj, attrs) {
return _.find(obj, _.matcher(attrs));
};

// Return the maximum element (or element-based computation).
// 返回list中的最大值。假如通报iteratee参数,iteratee将作为list中每一个值的排序依据。
// 假如list为空,将返回-Infinity,所以你能够须要事先用isEmpty搜检 list 。

_.max = function(obj, iteratee, context) {
var result = -Infinity,
lastComputed = -Infinity,
value, computed;
if (iteratee == null || typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null) {
obj = isArrayLike(obj) ? obj : _.values(obj);
for (var i = 0, length = obj.length; i value = obj[i];
if (value != null && value > result) {
result = value;
}
}
} else {
iteratee = cb(iteratee, context);
_.each(obj, function(v, index, list) {
computed = iteratee(v, index, list);
if (computed > lastComputed || computed === -Infinity && result === -Infinity) {
result = v;
lastComputed = computed;
}
});
}
return result;
};

// Return the minimum element (or element-based computation).
// 返回list中的最小值。假如通报iteratee参数,iteratee将作为list中每一个值的排序依据。
// 假如list为空,将返回Infinity,所以你能够须要事先用isEmpty搜检 list 。

_.min = function(obj, iteratee, context) {
var result = Infinity,
lastComputed = Infinity,
value, computed;
if (iteratee == null || typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null) {
obj = isArrayLike(obj) ? obj : _.values(obj);
for (var i = 0, length = obj.length; i value = obj[i];
if (value != null && value result = value;
}
}
} else {
iteratee = cb(iteratee, context);
_.each(obj, function(v, index, list) {
computed = iteratee(v, index, list);
if (computed result = v;
lastComputed = computed;
}
});
}
return result;
};

// Shuffle a collection.

_.shuffle = function(obj) {
return _.sample(obj, Infinity);
};

// Sample n random values from a collection using the modern version of the
// Fisher-Yates shuffle.
// If n is not specified, returns a single random element.
// The internal guard argument allows it to work with map.
// 从 list中发生一个随机样本。通报一个数字示意从list中返回n个随机元素。否则将返回一个单一的随机项。

_.sample = function(obj, n, guard) {
if (n == null || guard) {
if (!isArrayLike(obj)) obj = _.values(obj);
return obj[_.random(obj.length - 1)];
}
var sample = isArrayLike(obj) ? _.clone(obj) : _.values(obj);
var length = getLength(sample);
//取一个相符0-length的合理值
n = Math.max(Math.min(n, length), 0);
var last = length - 1;
for (var index = 0; index var rand = _.random(index, last);
var temp = sample[index];
sample[index] = sample[rand];
sample[rand] = temp;
}
return sample.slice(0, n);
};

// Sort the object&#8217;s values by a criterion produced by an iteratee.
// 返回一个(稳固的)排序后的list拷贝副本。
// 假如通报iteratee参数,iteratee将作为list中每一个值的排序依据。
// 用来举行排序迭代器也能够是属性称号的字符串(比方 length)。

_.sortBy = function(obj, iteratee, context) {
var index = 0;
iteratee = cb(iteratee, context);
return _.pluck(_.map(obj, function(value, key, list) {
return {
value: value,
index: index++,
criteria: iteratee(value, key, list)
};
}).sort(function(left, right) {
var a = left.criteria;
var b = right.criteria;
if (a !== b) {
if (a > b || a === void 0) return 1;
if (a }
return left.index - right.index;
}), 'value');
};

// An internal function used for aggregate &#8220;group by&#8221; operations.
// 对鸠合每一个元素挪用iteratee函数后,获得key。
// 然后再依据behavior举行分组

var group = function(behavior, partition) {
return function(obj, iteratee, context) {
var result = partition ? [
[],
[]
] : {};
iteratee = cb(iteratee, context);
_.each(obj, function(value, index) {
var key = iteratee(value, index, obj);
behavior(result, value, key);
});
return result;
};
};

// Groups the object&#8217;s values by a criterion. Pass either a string attribute
// to group by, or a function that returns the criterion.
// 把一个鸠合分组为多个鸠合,经由过程 iterator 返回的效果举行分组.
// 假如 iterator 是一个字符串而不是函数, 那末将运用 iterator 作为各元素的属性名来对照举行分组。

_.groupBy = group(function(result, value, key) {
if (has(result, key)) result[key].push(value);
else result[key] = [value];
});

// Indexes the object&#8217;s values by a criterion, similar to groupBy, but for
// when you know that your index values will be unique.
// 给定一个list,和 一个用来返回一个在列表中的每一个元素键 的iterator 函数(或属性名), 返回一个每一项索引的对象。
// 和groupBy异常像,然则当你晓得你的键是唯一的时刻能够运用indexBy 。

_.indexBy = group(function(result, value, key) {
result[key] = value;
});

// Counts instances of an object that group by a certain criterion. Pass
// either a string attribute to count by, or a function that returns the
// criterion.
// 排序一个列表构成多个组,而且返回各组中的对象的数量的计数。
// 相似groupBy,然则不是返回列表的值,而是返回在该组中值的数量。

_.countBy = group(function(result, value, key) {
if (has(result, key)) result[key]++;
else result[key] = 1;
});

var reStrSymbol = /1|ud800-udbff|[ud800-udfff]/g;
// Safely create a real, live array from anything iterable.

_.toArray = function(obj) {
if (!obj) return [];
if (_.isArray(obj)) return slice.call(obj);
if (_.isString(obj)) {
// Keep surrogate pair characters together
return obj.match(reStrSymbol);
}
if (isArrayLike(obj)) return _.map(obj, _.identity);
return _.values(obj);
};

// Return the number of elements in an object.

_.size = function(obj) {
if (obj == null) return 0;
return isArrayLike(obj) ? obj.length : _.keys(obj).length;
};

// Split a collection into two arrays: one whose elements all satisfy the given
// predicate, and one whose elements all do not satisfy the predicate.
// 将 list 拆分为两个数组:第一个数组其元素都满足predicate迭代函数, 而第二个的一切元素均不能满足predicate迭代函数。
// predicate 经由过程 iteratee 举行转换,以简化速记语法。

_.partition = group(function(result, value, pass) {
result[pass ? 0 : 1].push(value);
}, true);

  1. ud800-udfff &#x21a9;

推荐阅读
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • Android自定义控件绘图篇之Paint函数大汇总
    本文介绍了Android自定义控件绘图篇中的Paint函数大汇总,包括重置画笔、设置颜色、设置透明度、设置样式、设置宽度、设置抗锯齿等功能。通过学习这些函数,可以更好地掌握Paint的用法。 ... [详细]
  • Arduino + ESP32C3 + TFT(1.8‘ ST7735S)基础平台(实验四)直接显示网络图片
    ------------------------------------------------------------------------------------------ ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • Html5-Canvas实现简易的抽奖转盘效果
    本文介绍了如何使用Html5和Canvas标签来实现简易的抽奖转盘效果,同时使用了jQueryRotate.js旋转插件。文章中给出了主要的html和css代码,并展示了实现的基本效果。 ... [详细]
  • 本文介绍了Windows操作系统的版本及其特点,包括Windows 7系统的6个版本:Starter、Home Basic、Home Premium、Professional、Enterprise、Ultimate。Windows操作系统是微软公司研发的一套操作系统,具有人机操作性优异、支持的应用软件较多、对硬件支持良好等优点。Windows 7 Starter是功能最少的版本,缺乏Aero特效功能,没有64位支持,最初设计不能同时运行三个以上应用程序。 ... [详细]
  • 本文介绍了OpenStack的逻辑概念以及其构成简介,包括了软件开源项目、基础设施资源管理平台、三大核心组件等内容。同时还介绍了Horizon(UI模块)等相关信息。 ... [详细]
  • 本文介绍了使用哈夫曼树实现文件压缩和解压的方法。首先对数据结构课程设计中的代码进行了分析,包括使用时间调用、常量定义和统计文件中各个字符时相关的结构体。然后讨论了哈夫曼树的实现原理和算法。最后介绍了文件压缩和解压的具体步骤,包括字符统计、构建哈夫曼树、生成编码表、编码和解码过程。通过实例演示了文件压缩和解压的效果。本文的内容对于理解哈夫曼树的实现原理和应用具有一定的参考价值。 ... [详细]
  • 本文讨论了在VMWARE5.1的虚拟服务器Windows Server 2008R2上安装oracle 10g客户端时出现的问题,并提供了解决方法。错误日志显示了异常访问违例,通过分析日志中的问题帧,找到了解决问题的线索。文章详细介绍了解决方法,帮助读者顺利安装oracle 10g客户端。 ... [详细]
  • 问题背景:callback回调函数算是js里的一个大头,我之前是模仿式写代码,并没有领会到callback的本质。后来遇到了个同步异步的问 ... [详细]
  • 基于TensorFlow的Keras高级API实现手写体数字识别
    前言这个项目的话我也是偶然在B站看到一个阿婆主(SvePana)在讲解这个,跟着他的视频敲的代码并学习起来的。并写在自己这里做个笔记也为 ... [详细]
author-avatar
星晴SOS
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有