1. ホーム
  2. javascript

[解決済み] なぜnodelistにはforEachがないのですか?

2022-11-20 17:46:02

質問

を変更する短いスクリプトを作成していました。 <abbr> 要素の内側のテキストを変更する短いスクリプトを作成していましたが nodelist には forEach メソッドを使用します。 私が知っているのは nodelist を継承していないことは知っています。 Array のような気がしませんか? forEach は便利なメソッドだと思いませんか?私の知らない特別な実装上の問題があって、そのために forEachnodelist ?

注:DojoとjQueryはどちらも forEach を何らかの形でノデリストに使用していることは知っています。 私は制限のため、どちらも使用できません。

どのように解決するのですか?

NodeList は現在、すべての主要なブラウザで forEach() を備えています。

参照 MDN の nodeList forEach() を参照してください。 .

オリジナルの回答

どの回答も なぜ NodeList は Array を継承していないので、NodeList に forEach といった具合です。

答えが見つかりました このes-discussのスレッドにあります。 . 要するに、それはウェブを壊してしまうのです。

問題は、Array.prototype.concat と組み合わせて、インスタンスが配列であることを意味する instanceof を誤って仮定するコードでした。

Google の Closure ライブラリにバグがあり、これが原因でほとんどすべての Google のアプリが失敗していました。このバグが発見されるとすぐにライブラリは更新されましたが、concat と組み合わせて同じ不正確な仮定を行うコードがまだ存在する可能性があります。

つまり、あるコードは次のようなことをしていました。

if (x instanceof Array) {
  otherArray.concat(x);
} else {
  doSomethingElseWith(x);
}

しかし concat は、quot;real" 配列(instanceof Arrayではない)を他のオブジェクトと区別して扱います。

[1, 2, 3].concat([4, 5, 6]) // [1, 2, 3, 4, 5, 6]
[1, 2, 3].concat(4) // [1, 2, 3, 4]

ということは、上のコードが壊れたのは x が NodeList であったときに壊れたということです。 doSomethingElseWith(x) のパスを通ったのに対し、その後では otherArray.concat(x) というパスを通るので、何か変なことになりました。 x が本当の配列でなかったため、奇妙なことになりました。

しばらくの間 Elements クラスが提案されていましたが、これは Array の本当のサブクラスであり、新しい NodeList" として使用されます。しかし、それは から削除され、DOM 標準 というのも、さまざまな技術的および仕様上の理由から、まだ実装することが現実的でなかったからです。