这里有一个将数组细分为更小块的解决方案。该解决方案在数组项上使用长度属性,这对我来说没有意义,因为它应该是未定义的;然而,该解决方案确实有效,当我在chrome-dev工具中使用调试器将其作为一个片段运行时,它确实显示了一个值,我只是不确定它是如何工作的。我无法解释为什么last.length
有任何价值。有人能解释一下为什么它有效,为什么我不能console.log为它记录一个值吗?
const chunk = (arr, size) => {
let newArr = []
for (let el of arr) {
let last = newArr[newArr.length -1]
console.log(last, 'i am last')
if(!last || last.length === size) {
newArr.push([el])
} else {
last.push(el)
}
}
return newArr
}
// chunk([1, 2, 3, 4, 5], 2) --> [[ 1, 2], [3, 4], [5]]
TLDR:当last
未定义时,此表达式
(!last || last.length === size)
仍然评估为true。请继续阅读以了解更多详细信息。
在循环的第一次迭代中,出现以下分配:
let last = newArr[-1];
因此,last被指定为undefined
作为值。
随后的声明:
if(!last || last.length === size) {
!last
的求值结果为true,因为这就是!undefined
的求值结果。
由于!last
为真,所以根本不评估last.length
。因此,没有出现任何异常,因为没有实际尝试评估undefined.length
的本质。这是大多数流行编程语言的一个功能,称为布尔短路。一旦OR表达式的第一部分求值为true,它右边的任何内容都不会求值。当左表达式的计算结果为false时,同样的主体也适用于AND语句。
这触发了下一行:
newArr.push([el])
这为数组提供了一个有效元素。因此CCD_ 9现在是1。
在循环的后续迭代中,last被正确地分配给newArr
中的最后一个元素。
您可以将last
的声明移到循环之外,并防止每个项都有对newArr
的新访问。
const chunk = (arr, size) => {
let newArr = [];
let last;
for (let el of arr) {
if (!last || last.length === size) {
last = [];
newArr.push(last);
}
last.push(el);
}
return newArr
}
console.log(chunk([1, 2, 3, 4, 5], 2));
妮娜·朔尔茨建议的变体,只是完全摆脱了undefined
的魔力:
const chunk = (arr, size) => {
let last = [];
let newArr = [last];
for (let el of arr) {
if (last.length === size) {
last = [];
newArr.push(last);
}
last.push(el);
}
return newArr
}
console.log(chunk([1, 2, 3, 4, 5], 2));