노드 목록에 forEach가없는 이유는 무엇입니까?
<abbr>
요소의 내부 텍스트 를 변경하기 위해 짧은 스크립트를 작성하고 있었지만 방법 nodelist
이 없음을 발견했습니다 forEach
. 나는 그것이 nodelist
에서 상속하지 않는다는 것을 알고 Array
있지만 forEach
유용한 방법 이 아닌 것 같 습니까? 추가 forEach
할 수없는 특정 구현 문제 가 nodelist
있습니까?
참고 : Dojo와 jQuery는 모두 forEach
노드 목록에 대해 어떤 형태로든 있다는 것을 알고 있습니다. 제한으로 인해 사용할 수 없습니다.
NodeList는 이제 모든 주요 브라우저에서 forEach ()를 갖습니다.
MDN의 nodeList forEach ()를 참조하십시오 .
원래 답변
이 답변 중 어느 것도 NodeList가 Array에서 상속하지 않는 이유를 설명 하지 않으므로 forEach
나머지 는 모두 가질 수 있습니다 .
대답은 이 es-discuss 스레드 에서 찾을 수 있습니다. 요컨대, 웹을 깨뜨립니다.
문제는 instanceof가 인스턴스가 Array.prototype.concat과 결합 된 Array임을 의미하는 것으로 잘못 가정 한 코드였습니다.
Google의 Closure Library에 버그가있어서 거의 모든 Google 앱이 이로 인해 실패했습니다. 라이브러리는 이것이 발견 되 자마자 업데이트되었지만 concat과 함께 동일한 잘못된 가정을 만드는 코드가 여전히있을 수 있습니다.
즉, 일부 코드는 다음과 같은 작업을 수행했습니다.
if (x instanceof Array) {
otherArray.concat(x);
} else {
doSomethingElseWith(x);
}
그러나 concat
"실제"배열 (배열의 인스턴스가 아님)을 다른 객체와 다르게 취급합니다.
[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 표준에서 제거되었습니다 .
넌 할 수있어
Array.prototype.forEach.call (nodeList, function (node) {
// Your code here.
} );
새로운 노드 배열 생성을 고려할 수 있습니다.
var nodeList = document.getElementsByTagName('div'),
nodes = Array.prototype.slice.call(nodeList,0);
// nodes is an array now.
nodes.forEach(function(node){
// do your stuff here.
});
참고 : 이것은 여기서 생성하는 노드 참조의 목록 / 배열 일 뿐이며 중복 노드는 없습니다.
nodes[0] === nodeList[0] // will be true
결코 말하지 마십시오. 2016 년이고 NodeList
객체는 forEach
최신 크롬 (v52.0.2743.116)에서 메서드를 구현했습니다 .
다른 브라우저가 아직이를 지원하지 않기 때문에 프로덕션에서 사용하기에는 너무 이르지만 (테스트 된 FF 49) 조만간 표준화 될 것이라고 생각합니다.
요컨대, 그 방법을 구현하는 것은 디자인 충돌입니다.
MDN에서 :
NodeList에서 forEach 또는 map을 사용할 수없는 이유는 무엇입니까?
NodeList는 배열과 매우 유사하게 사용되며 Array.prototype 메소드를 사용하고 싶을 것입니다. 그러나 이것은 불가능합니다.
JavaScript에는 프로토 타입을 기반으로하는 상속 메커니즘이 있습니다. 배열 인스턴스는 프로토 타입 체인이 다음과 같기 때문에 배열 메서드 (예 : forEach 또는 map)를 상속합니다.
myArray --> Array.prototype --> Object.prototype --> null
(객체의 프로토 타입 체인은 Object.getPrototypeOf를 여러 번 호출하여 얻을 수 있습니다.)forEach, map and the likes are own properties of the Array.prototype object.
Unlike arrays, NodeList prototype chain looks like the following:
myNodeList --> NodeList.prototype --> Object.prototype --> null
NodeList.prototype contains the item method, but none of the Array.prototype methods, so they cannot be used on NodeLists.
Source: https://developer.mozilla.org/en-US/docs/DOM/NodeList (scroll down to Why can't I use forEach or map on a NodeList?)
If you would like using forEach on NodeList, just copy that function from Array:
NodeList.prototype.forEach = Array.prototype.forEach;
Thats all, now you can use it at the same manner you would for Array:
document.querySelectorAll('td').forEach(function(o){
o.innerHTML = 'text';
});
In ES2015, you can now use forEach
method to the nodeList.
document.querySelectorAll('abbr').forEach( el => console.log(el));
See The MDN Link
However if you want to use HTML Collections or other array-like objects, in es2015, you can use Array.from()
method. This method takes an array-like or iterable object (including nodeList, HTML Collections, strings etc) and returns a new Array instance. You can use it like this:
const elements = document.getElementsByTagName('abbr');
Array.from(elements).forEach( el => console.log(el));
As Array.from()
method is shimmable, you can use it in es5 code like this
var elements = document.getElementsByTagName('abbr');
Array.from(elements).forEach( function(el) {
console.log(el);
});
For details, see the MDN page.
To check current browser support.
OR
another es2015 way is to use spread operator.
[...document.querySelectorAll('abbr')].forEach( el => console.log(el));
Spread Operator - Browser Support
My solution:
//foreach for nodeList
NodeList.prototype.forEach = Array.prototype.forEach;
//foreach for HTML collection(getElementsByClassName etc.)
HTMLCollection.prototype.forEach = Array.prototype.forEach;
NodeList is part of the DOM API. Look at the ECMAScript bindings which apply to JavaScript as well. http://www.w3.org/TR/DOM-Level-2-Core/ecma-script-binding.html. The nodeList and a read-only length property and item(index) function to return a node.
The answer is, you have to iterate. There is no alternative. Foreach will not work. I work with Java DOM API bindings and have the same problem.
Check MDN for NodeList.forEach specification.
NodeList.forEach(function(item, index, nodeList) {
// code block here
});
In IE, use akuhn's answer:
[].forEach.call(NodeList, function(item, index, array) {
// code block here
});
참고URL : https://stackoverflow.com/questions/13433799/why-doesnt-nodelist-have-foreach
'developer tip' 카테고리의 다른 글
Android Studio를 사용한 디버깅이 "Waiting For Debugger"에서 영원히 멈춤 (0) | 2020.09.15 |
---|---|
Rails 3 : Ajax 호출에서 "redirect_to"하는 방법? (0) | 2020.09.15 |
AJAX MVC를 통해 Excel 파일 다운로드 (0) | 2020.09.15 |
CSS를 통한 자동 완성 비활성화 (0) | 2020.09.15 |
배열 재정렬 (0) | 2020.09.15 |