从下划线返回 false each 似乎结束了循环
Returning false from underscore each appears to end the loop
我在使用 Underscore 的 _.each
函数时遇到了一些莫名其妙的行为。对于我正在创建的一组对象,我在基础 class 中有以下内容:
constructor(properties = {}, options = {}) {
// lets me replace UUID generator function for testing, and for a
// special-case id used by a singleton subclass
_.defaults(options, {generateUuid});
_.chain(properties)
.keys()
.reject((k) => k === 'id' || k === '_id')
.each((k) => this[k] = properties[k])
.value();
this._id = options.generateUuid();
}
在测试我的第一个大型子class 的构造函数时,我传入了大量属性(数字、字符串和布尔值)。我的 Chai 断言在第 43 个 属性(共 61 个)处失败,紧接在第一个 false
值之后。该错误声称 属性 不存在。
有问题的子class的当前状态很简单:
constructor(properties = {}) {
if (typeof properties.subtype !== 'undefined') {
properties._subtype = properties.subtype;
}
// etc. for several more aliased properties
_.defaults(properties, {
_subtype: 'token',
// etc. for default property values
});
super({
_type: 'graphic',
_subtype: properties._subtype,
// etc. for all whitelisted properties
});
}
在尝试调试问题时,我确认所有属性及其正确值都已传递给 superclass 构造函数,但第一个 false
之后的所有属性都没有传递加入 this
。只有当我向 .each
添加跟踪调试时,事情才真正改变:
_.chain(properties)
.keys()
.reject((k) => k === 'id' || k === '_id')
.each((k) => {
console.log(k);
this[k] = properties[k];
})
.value();
突然间,对象中出现了所有属性,我的测试通过了!由于单行箭头函数(不带括号)返回其单个表达式的值(而多行箭头函数默认返回未定义),并且表达式 foo = bar
returns bar,我的唯一的结论是从 _.each
返回 false
结束循环。
所以,我着手调查为什么会这样。我抓取了 Underscore 源代码(v1.8.3,与我 运行 相同的版本),看看是否有专门的特殊处理来实现该结果(这将方便地允许客户端代码 break
来自_.each
循环):
_.each = _.forEach = function(obj, iteratee, context) {
iteratee = optimizeCb(iteratee, context);
var i, length;
if (isArrayLike(obj)) {
for (i = 0, length = obj.length; i < length; i++) {
iteratee(obj[i], i, obj);
}
} else {
var keys = _.keys(obj);
for (i = 0, length = keys.length; i < length; i++) {
iteratee(obj[keys[i]], keys[i], obj);
}
}
return obj;
};
当context
为假时,optimizeCb(iteratee, context)
立即returnsiteratee
。当 iteratee
returns false.
时,这里没有什么应该提前爆发的
有人对我观察到的行为有解释吗?
您似乎在使用 lodash and not underscore。
The iteratee is invoked with three arguments: (value, index|key, collection). Iteratee functions may exit iteration early by explicitly returning false
.
我在使用 Underscore 的 _.each
函数时遇到了一些莫名其妙的行为。对于我正在创建的一组对象,我在基础 class 中有以下内容:
constructor(properties = {}, options = {}) {
// lets me replace UUID generator function for testing, and for a
// special-case id used by a singleton subclass
_.defaults(options, {generateUuid});
_.chain(properties)
.keys()
.reject((k) => k === 'id' || k === '_id')
.each((k) => this[k] = properties[k])
.value();
this._id = options.generateUuid();
}
在测试我的第一个大型子class 的构造函数时,我传入了大量属性(数字、字符串和布尔值)。我的 Chai 断言在第 43 个 属性(共 61 个)处失败,紧接在第一个 false
值之后。该错误声称 属性 不存在。
有问题的子class的当前状态很简单:
constructor(properties = {}) {
if (typeof properties.subtype !== 'undefined') {
properties._subtype = properties.subtype;
}
// etc. for several more aliased properties
_.defaults(properties, {
_subtype: 'token',
// etc. for default property values
});
super({
_type: 'graphic',
_subtype: properties._subtype,
// etc. for all whitelisted properties
});
}
在尝试调试问题时,我确认所有属性及其正确值都已传递给 superclass 构造函数,但第一个 false
之后的所有属性都没有传递加入 this
。只有当我向 .each
添加跟踪调试时,事情才真正改变:
_.chain(properties)
.keys()
.reject((k) => k === 'id' || k === '_id')
.each((k) => {
console.log(k);
this[k] = properties[k];
})
.value();
突然间,对象中出现了所有属性,我的测试通过了!由于单行箭头函数(不带括号)返回其单个表达式的值(而多行箭头函数默认返回未定义),并且表达式 foo = bar
returns bar,我的唯一的结论是从 _.each
返回 false
结束循环。
所以,我着手调查为什么会这样。我抓取了 Underscore 源代码(v1.8.3,与我 运行 相同的版本),看看是否有专门的特殊处理来实现该结果(这将方便地允许客户端代码 break
来自_.each
循环):
_.each = _.forEach = function(obj, iteratee, context) {
iteratee = optimizeCb(iteratee, context);
var i, length;
if (isArrayLike(obj)) {
for (i = 0, length = obj.length; i < length; i++) {
iteratee(obj[i], i, obj);
}
} else {
var keys = _.keys(obj);
for (i = 0, length = keys.length; i < length; i++) {
iteratee(obj[keys[i]], keys[i], obj);
}
}
return obj;
};
当context
为假时,optimizeCb(iteratee, context)
立即returnsiteratee
。当 iteratee
returns false.
有人对我观察到的行为有解释吗?
您似乎在使用 lodash and not underscore。
The iteratee is invoked with three arguments: (value, index|key, collection). Iteratee functions may exit iteration early by explicitly returning
false
.