web-dev-qa-db-ja.com

Javascript要素のコレクションでArray.forEachを使用できないのはなぜですか?

Babel/ES6でアプリを作成しています。表示専用バージョンのすべてのフォーム要素を無効にしたいので、次のようにしました。

_let form = document.getElementById('application-form')
let elements = form.elements
_

通常の古いforループ(機能しました)を使用する代わりに、これを実行できると期待していました。

_elements.forEach((el) => {
    el.disabled = true
})
_

しかし、私は_TypeError: elements.forEach is not a function_を手に入れました

奇妙なことに、Chrome devconsoleでconsole.log(elements)を実行すると、inputオブジェクトがたくさんある配列とまったく同じになります。オブジェクトのObject表記、およびすべてのキーは整数です。これはある種の疑似配列だと思いますが、それを見つける方法すら知りません。

[〜#〜] edit [〜#〜]:短い答えこれは配列ではなく、HTMLCollectionです。参照 ノードリストにforEachがないのはなぜですか?


*更新*

この回答 ごとに、nodelistforEachメソッドが追加されました!

8
inostia

あなたはできる。 forEachHTMLFormControlsCollectionプロパティがないため、それを使用することはできませんlike thatform.elements が提供します(配列ではありません)。

とにかくそれを使用する方法は次のとおりです。

Array.prototype.forEach.call(form.elements, function(element) {
    // ...
});

またはあなたmayスプレッド表記を使用できる:

[...elements].forEach(function(element) {
    // ...
});

...ただし、ブラウザのHTMLFormControlsCollection実装がiterableであることに依存していることに注意してください。


または、代わりにArray.from(ポリフィルが必要ですが、ES2015にタグを付けたので...):

Array.from(elements).forEach(function(element) {
    // ...
});

詳細については、"array-like"ここに私の答え の一部を参照してください。

15
T.J. Crowder

あなたはできませんforEachHMTLCollectionで使用します。 forEachは `配列でのみ使用できます。

別の方法は、 lodash を使用し、_.toArray()を実行します。これにより、HTMLColelctionが配列に変換されます。その後、通常のアレイ操作を実行できます。または、ES6 spreadを使用してforEach()を実行します

このような、

var a = document.getElementsByTagName('div')
[...a].forEach()
1
Pranesh Ravi

_form.elements_、_document.getElementsByTagName_、_document.getElementsByClassName_、および_document.querySelectorAll_はノードリストを返します。

ノードリストは基本的に、配列のようなメソッドを持たないオブジェクトです。

ノードリストを配列として使用する場合は、Array.from(NodeList)またはArray.prototype.slice.call(NodeList)の古い方法を使用できます。

_// es6
const thingsNodeList = document.querySelectorAll('.thing')
const thingsArray = Array.from(thingsNodeList)
thingsArray.forEach(thing => console.log(thing.innerHTML))

// es5
var oldThingsNodeList = document.getElementsByClassName('thing')
var oldThingsArray = Array.prototype.slice.call(oldThingsNodeList)
thingsArray.forEach(function(thing){ 
  console.log(thing.innerHTML) 
})_
_<div class="thing">one</div>
<div class="thing">two</div>
<div class="thing">three</div>
<div class="thing">four</div>_
0
synthet1c