break相當於循環中的GOTO,需避免使用。
下面是一個break使用例子。
找出第一個months小於7的項目。
const cats = [
{ name: 'Mojo', months: 84 },
{ name: 'Mao-Mao', months: 34 },
{ name: 'Waffles', months: 4 },
{ name: 'Pickles', months: 6 }
]
const isKitten = cat => cat.months < 7
var firstKitten
for (var i = 0; i < cats.length; i++) {
if (isKitten(cats[i])) {
firstKitten = cats[i]
break
}
}
類似的例子,找出前五個項目。
var first5Kittens = []
// old-school edge case kitty loop
for (var i = 0; i < cats.length; i++) {
if (isKitten(cats[i])) {
first5Kittens.push(cats[i])
if (first5Kittens.length >= 5) {
break
}
}
}
對上面的例子進行改造。
用函數封裝下。用limit來代替5,predicate來代替isKitten,list來代替cats。然后把這些作為函數的參數。
const takeFirst = (limit, predicate, list) => {
const newList = []
for (var i = 0; i < list.length; i++) {
if (predicate(list[i])) {
newList.push(list[i])
if (newList.length >= limit) {
break
}
}
}
return newList
}
使用遞歸形式來表示循環,跳出遞歸即break。
const takeFirst = (limit, predicate, list, i = 0, newList = []) => {
const isDone = limit <= 0 || i >= list.length
const isMatch = isDone ? undefined : predicate(list[i])
if (isDone) {
return newList
} else if (isMatch) {
return takeFirst(limit - 1, predicate, list, i + 1, [...newList, list[i]])
} else {
return takeFirst(limit, predicate, list, i + 1, newList)
}
}
使用第三方庫Lazy.js
來實現這個需求。
const result = Lazy(cats)
.filter(isKitten)
.take(5)
參考:
https://hackernoon.com/rethinking-javascript-break-is-the-goto-of-loops-51b27b1c85f8