function remove(array, predicate)
从 array
中删除所有 predicate
返回真值的元素,并返回已删除元素的数组。
@param {Array} array The array to modify.
要修改的数组
@param {Function} [predicate=_.identity] The function invoked per iteration.
每次迭代调用的函数。
function remove(array, predicate) {
// 创建一个新数组
var result = [];
// 数组如果不存在或空数组,直接返回result
if (!(array && array.length)) {
return result;
}
// 循环数组需要用到的下标
var index = -1,
// 循环时存储被删除的元素下标数组
indexes = [],
// 数组的长度
length = array.length;
// 处理第二个参数,无论第二个参数有没有传递,都将会调用getIteratee来处理它
predicate = getIteratee(predicate, 3);
// 循环数组
while (++index < length) {
// 获取当前项
var value = array[index];
// 调用predictate方法
if (predicate(value, index, array)) {
// 将被删除的内容添加到result
result.push(value);
// 将被删除的内容的下标添加到indexes
indexes.push(index);
}
}
// 调用basePullAt删除原数组对应下标的内容
basePullAt(array, indexes);
// 返回被删除的元素数组
return result;
}
(心累啊,一环套一环,我只想看个remove结果没想到)
function getIteratee()
获取相应的“迭代”函数。 如果自定义了_.iteratee
,则该函数返回自定义方法,否则返回baseIteratee
。 如果提供了参数,则使用它们调用所选函数并返回其结果。
@param {*} [value] The value to convert to an iteratee.
转换为迭代对象的值
@param {number} [arity] The arity of the created iteratee.
创建的迭代对象的数量
function getIteratee() {
// 赋值iteratee函数
var result = lodash.iteratee || iteratee;
// 判断result此时和原函数iteratee是否相同?若相同,更改为base版本,若不相同,保持原样
result = result === iteratee ? baseIteratee : result;
// 判断是否传递了参数,若没有定义形参,那么是使用arguments来拿到函数中的参数,并将两个参数分别传入result(也是baseIteratee)
return arguments.length ? result(arguments[0], arguments[1]) : result;
}
function baseIteratee(value)
_.iteratee
的基本实现。
@param {*} [value=_.identity] The value to convert to an iteratee.
要转换为迭代对象的值
function baseIteratee(value) {
// Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.
// 不要将 `typeof` 结果存储在变量中,以避免 Safari 9 中出现 JIT 错误。
// See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.
// 有关详细信息,请参阅 https://bugs.webkit.org/show_bug.cgi?id=156034。
// 如果该参数的类型为function,直接返回其参数
if (typeof value == 'function') {
return value;
}
// 如果该参数未传递[undefined]或其他,与null相等,则返回 identity 方法
if (value == null) {
return identity;
}
// 如果该参数的类型为object(可能多半为数组)
if (typeof value == 'object') {
// 判断该参数是否是数组
return isArray(value)
// 调用baseMatchesProperty
? baseMatchesProperty(value[0], value[1])
// 调用baseMatches
: baseMatches(value);
}
// 调用property
return property(value);
}
function identity(value)
此方法返回它接收到的第一个参数。
@param {*} value Any value.
任何值
function identity(value) {
return value;
}
function baseMatchesProperty(path, srcValue)
'matchesProperty'的基本实现,它不克隆'srcValue'。
@param {string} path The path of the property to get.
要获取的属性的路径。
@param {*} srcValue The value to match.
要匹配的值。
(这个调用到的函数太多了, 之后再看吧,我已经记在小本本上了)
function baseMatchesProperty(path, srcValue) {
if (isKey(path) && isStrictComparable(srcValue)) {
return matchesStrictComparable(toKey(path), srcValue);
}
return function(object) {
var objValue = get(object, path);
return (objValue === undefined && objValue === srcValue)
? hasIn(object, path)
: baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);
};
}
function isKey(value, object)
检查“value”是否是属性名而不是属性路径。
如果'value'是属性名,则返回'true',否则返回'false'。
@param {*} value The value to check.
要检查的值
@param {Object} [object] The object to query keys on.
要查询密钥的对象
function isKey(value, object) {
// 是数组吗?因为数组也是对象
if (isArray(value)) {
// 如果是数组返回FALSE,数组没有属性,该函数判断的是对象
return false;
}
// 保存该查询值的类型
var type = typeof value;
// 当查询值的类型是:
// 数字、symbol、布尔、undefined、null、
if (type == 'number' || type == 'symbol' || type == 'boolean' ||
value == null || isSymbol(value) ) {
// 返回true
return true;
}
//
return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
(object != null && value in Object(object));
}
function isSymbol(value)
检查“value”是否被归类为“Symbol”原型或对象。
@param {*} value The value to check.
要检查的值
function isSymbol(value) {
// 返回两种
// 如果类型是symbol,返回true
// 否则先调用isObjectLike判断是否是类对象,若不是,返回false,若是,再调用baseGetTag和symbolTag判断
return typeof value == 'symbol' ||
(isObjectLike(value) && baseGetTag(value) == symbolTag);
}
function isObjectLike(value)
检查“value”是否与对象类似。如果一个值不是'null',并且有一个'typeof'结果为“object”,那么它就是object。
@param {*} value The value to check.
要检查的值
function isObjectLike(value) {
// value不等于null并且value类型为object
return value != null && typeof value == 'object';
}
(后面的先略过吧。已经和remove无关了)
function basePullAt(array, indexes)
pullAt的基本实现,不支持单个索引或捕获删除的元素。
@param {Array} array The array to modify.
要修改的数组
@param {number[]} indexes The indexes of elements to remove.
要删除的元素的索引[由下标组成的数组]
function basePullAt(array, indexes) {
// 数组存在则获取删除元素下标数组的长度,默认为0
var length = array ? indexes.length : 0,
// 删除元素下标数组的数组最大索引值
lastIndex = length - 1;
// 循环
while (length--) {
// 从后往前删除,因为如果删除前面的元素的话,数组的内容会变化,从而导致后面的下标无法匹配正确的内容
// 取出当前要删除的下标
var index = indexes[length];
// 判断条件:length == lastIndex 第一次是满足条件的
// 第二次判断,var定义变量会有变量提升声明,所以此时调用的previous为undefined
// 此时index为数组下标,必定满足判断条件
if (length == lastIndex || index !== previous) {
// 重新赋值(如果多个下标)
var previous = index;
// 判断index是否是合理的数组下标
if (isIndex(index)) {
// 调用splice截取,删除对应的元素1位
splice.call(array, index, 1);
} else {
// 删除对象对应路径的属性,这个放到明天看
baseUnset(array, index);
}
}
}
// 返回数组
return array;
}
网友评论