Javascript ES6.forEach方法不循环数组?

Javascript ES6.forEach方法不循环数组?,javascript,ecmascript-6,Javascript,Ecmascript 6,我的.forEach循环遇到一些问题。这是我目前的代码: let isPangram = (phrase) => { let alphabet = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]; alphabet.forEach(function(letter) {

我的
.forEach
循环遇到一些问题。这是我目前的代码:

let isPangram = (phrase) => {
  let alphabet = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"];
  alphabet.forEach(function(letter) {
    if (phrase.toLowerCase().includes(letter)) {
      alphabet.splice(alphabet.indexOf(letter), 1);
    }
    debugger;
  });
  if (alphabet.length === 0) {
    return true;
  }
  else if (alphabet.length > 0) {
    return false;
  }
};

当我使用
调试器在控制台中运行此命令时,它似乎跳过了一些字母,如
b
c
。有人能告诉我这里发生了什么吗?

在使用
.forEach()
进行迭代时,不应该从数组中删除当前元素。使用
.splice()
删除时,它会删除一个元素,数组中的元素随后会向下移动一个插槽,然后迭代的下一步将错过刚刚移动到当前迭代插槽中的元素

一种更安全的方法是使用传统的
for
循环,并从一端到前端向后迭代。然后,对数组所做的任何更改都将超出您正在迭代的范围。当然,可能有一种更好的方式来编写这篇文章,完全不需要拼接。就我个人而言,我可能会使用一个
Set
对象来跟踪所有使用过的字母,看看是否最终会得到所有26个字母

从:“如果在迭代过程中删除了已访问的元素(例如使用shift()),则将跳过后面的元素-参见下面的示例。”

另外,
forEach()
对于ES6来说并不是什么新鲜事,它从ES5开始就存在了


以下是一种使用一些ES6功能测试pangram的非删除方法:

const allCharsSet=新集合(“abcdefghijklmnopqrstuvwxyz”);
函数isPangram(短语){
让foundLetters=新集合();
for(让我们来说说短语){
ch=ch.toLowerCase();
如果(所有字符集有(ch)){
添加(ch);
}
}
return foundLetters.size==allCharsSet.size;
}
log(isPangram(“五位拳击奇才跳得很快”);
log(isPangram(“许多聪明的杰克嘲笑性测试的探针”);
log(isPangram(“演奏爵士乐和弦会让我妻子很快兴奋”);

log(isPangram(“其他短语”)谢谢!这很有道理。我最终创建了一个名为
matches
的新数组,每当我得到一个匹配项时,我就将字母推到新数组中,结果成功了。再次感谢@GeorgeLi-既然您提到了ES6,我就添加了一种ES6方法,这种方法不必从数组中删除内容。@GeorgeLi-既然您可能是新来的,如果这已经回答了您的问题,那么您可以通过单击答案左侧的绿色复选标记向社区表明这一点。这也会为您赢得一些声誉点数,从而在网站上获得更多特权。这是一个很好的解释,但解决方案可能会简单得多,因为有一种方法:@pawel-如果您认为使用
.every()
,它会简单得多,效率也一样高,然后,请发布您自己的答案,使用它实现
isPangram()
函数。这是一个有趣的高尔夫练习:
让isPangram=phrase=>新设置(phrase.toLowerCase().match(/[a-z]/g))。大小==26:D
返回字母表.every(字母=>短语.toLowerCase().includes(字母))