返回值时,`each` 与 `for-loop` 有何不同?
How is `each` different from `for-loop` when returning a value?
我创建了我的 each
函数来模拟 Underscore.js 的 _each()
用于我的 Javascript 学习。
var each = function(list, iteratee) {
if (Array.isArray(list)) { // list is array
for (var i = 0; i < list.length; i++) {
iteratee(list[i], i, list);
}
} else if (list.constructor === Object) { // list is object
for (var key in list) {
iteratee(list[key], key, list);
}
}
};
然后我想创建一个函数 find
,它也可以从 Underscore.js 获得。此函数查看 list
、return 中第一个通过真值测试 (predicate
) 的每个值,或
undefined
如果没有值通过测试。函数 returns 一旦找到可接受的元素并且不会遍历整个列表。
这是我想出的 find
版本。
var find = function(list, predicate) {
each(list, function(elem){
if (predicate(elem)) {
return elem;
}
});
};
我认为它会在找到通过外部谓词函数测试的元素的真值后立即 return 一个值。但相反,它给了我一个 undefined
.
下面的代码如我所料。但为什么他们会提供不同的输出?
var find = function(list, predicate) {
if (Array.isArray(list)) { // list is array
for (var i = 0; i < list.length; i++) {
if (predicate(list[i])) {
return list[i];
}
}
} else if (list.constructor === Object) { // list is object
for (var key in list) {
if (predicate(list[key])) {
return list[key];
}
}
}
};
我不明白的是,当我将 each
包含在我的 find
函数中时,为什么它没有像我预期的那样工作。他们不会只是表达方式不同吗?也就是说,一个是函数式风格,一个不是?
这是由于缺少return声明造成的。
每个函数迭代查找但不 return 任何东西。 return 谓词中的语句 returns 输出到每个函数的不期望的地方
工作函数示例:
var find = function(list, predicate) {
var res = undefined/null/whatever;
each(list, function(elem) {
if (predicate(elem)) {
res = elem;
}
});
return res;
};
但是这个函数效率不高,因为它不会在找到结果时停止
这与 return
的工作原理有关。让我们看看您的代码:
var find = function(list, predicate) {
// you pass list and an anonymous callback to `each`
each(list, function (elem) {
// if this condition is true
if (predicate(elem)) {
// return elem
return elem;
}
});
}
问题是 return elem
适用于匿名回调,而不是 find
函数。
如果您希望能够 "break" each
循环,您可以检查 each
.[=21= 中 for 循环每次迭代的当前状态]
// only going to write for arrays
var each = function (list, iteratee) {
for (var i = 0; i < list.length; i++) {
if (iteratee(list[i], i, list)) continue;
else break;
}
});
// then in find:
var find = function (list, predicate) {
var ret = null
each(list, function(elem) {
if (predicate(elem)) {
ret = elem;
return false; // return false, since we no longer wish to continue
}
});
return ret;
};
第二种解决方案是在 each
循环中 return:
var each = function (list, iteratee) {
for (var i = 0; i < list.length; i++) {
if (iteratee(list[i], i, list)) {
continue;
} else {
return list[i];
}
}
// didn't find anything, so `return null`
return null;
});
var find = function (list, predicate) {
return each(list, function(elem) {
// if `predicate`, return false, so the loop breaks
return !predicate(elem);
});
};
我对这个解决方案的唯一问题是它扭曲了 each
的含义。 each
直觉上意味着 "go through everything," 而第二个解决方案不一定如此。
我创建了我的 each
函数来模拟 Underscore.js 的 _each()
用于我的 Javascript 学习。
var each = function(list, iteratee) {
if (Array.isArray(list)) { // list is array
for (var i = 0; i < list.length; i++) {
iteratee(list[i], i, list);
}
} else if (list.constructor === Object) { // list is object
for (var key in list) {
iteratee(list[key], key, list);
}
}
};
然后我想创建一个函数 find
,它也可以从 Underscore.js 获得。此函数查看 list
、return 中第一个通过真值测试 (predicate
) 的每个值,或
undefined
如果没有值通过测试。函数 returns 一旦找到可接受的元素并且不会遍历整个列表。
这是我想出的 find
版本。
var find = function(list, predicate) {
each(list, function(elem){
if (predicate(elem)) {
return elem;
}
});
};
我认为它会在找到通过外部谓词函数测试的元素的真值后立即 return 一个值。但相反,它给了我一个 undefined
.
下面的代码如我所料。但为什么他们会提供不同的输出?
var find = function(list, predicate) {
if (Array.isArray(list)) { // list is array
for (var i = 0; i < list.length; i++) {
if (predicate(list[i])) {
return list[i];
}
}
} else if (list.constructor === Object) { // list is object
for (var key in list) {
if (predicate(list[key])) {
return list[key];
}
}
}
};
我不明白的是,当我将 each
包含在我的 find
函数中时,为什么它没有像我预期的那样工作。他们不会只是表达方式不同吗?也就是说,一个是函数式风格,一个不是?
这是由于缺少return声明造成的。 每个函数迭代查找但不 return 任何东西。 return 谓词中的语句 returns 输出到每个函数的不期望的地方
工作函数示例:
var find = function(list, predicate) {
var res = undefined/null/whatever;
each(list, function(elem) {
if (predicate(elem)) {
res = elem;
}
});
return res;
};
但是这个函数效率不高,因为它不会在找到结果时停止
这与 return
的工作原理有关。让我们看看您的代码:
var find = function(list, predicate) {
// you pass list and an anonymous callback to `each`
each(list, function (elem) {
// if this condition is true
if (predicate(elem)) {
// return elem
return elem;
}
});
}
问题是 return elem
适用于匿名回调,而不是 find
函数。
如果您希望能够 "break" each
循环,您可以检查 each
.[=21= 中 for 循环每次迭代的当前状态]
// only going to write for arrays
var each = function (list, iteratee) {
for (var i = 0; i < list.length; i++) {
if (iteratee(list[i], i, list)) continue;
else break;
}
});
// then in find:
var find = function (list, predicate) {
var ret = null
each(list, function(elem) {
if (predicate(elem)) {
ret = elem;
return false; // return false, since we no longer wish to continue
}
});
return ret;
};
第二种解决方案是在 each
循环中 return:
var each = function (list, iteratee) {
for (var i = 0; i < list.length; i++) {
if (iteratee(list[i], i, list)) {
continue;
} else {
return list[i];
}
}
// didn't find anything, so `return null`
return null;
});
var find = function (list, predicate) {
return each(list, function(elem) {
// if `predicate`, return false, so the loop breaks
return !predicate(elem);
});
};
我对这个解决方案的唯一问题是它扭曲了 each
的含义。 each
直觉上意味着 "go through everything," 而第二个解决方案不一定如此。