답변:
[]
배열입니다.
이 배열은 전혀 사용되지 않습니다.
배열을 사용하면과 같은 배열 프로토 타입에 액세스 할 수 있으므로 페이지에 표시 .forEach
됩니다.
입력하는 것보다 빠릅니다. Array.prototype.forEach.call(...);
다음으로, forEach
기능을 입력으로받는 기능입니다.
[1,2,3].forEach(function (num) { console.log(num); });
...의 각 요소에 대해 this
( this
어레이가 있고 배열이 있고 length
그 부분에 액세스 할 수 있다는 점에서 this[1]
)은 세 가지를 전달합니다.
2
)마지막으로, .call
함수가 가진 프로토 타입입니다 (다른 함수에서 호출되는 함수입니다).
.call
첫 번째 인자를 가지고 대체합니다 this
당신이 통과 무엇 이건 정규 함수의 내부에 call
첫 번째 인수로, ( undefined
또는 null
사용 window
일상 JS에서, 또는 당신이 경우 "엄격 모드"에서 통과 무엇이든 될 것입니다). 나머지 인수는 원래 함수로 전달됩니다.
[1, 2, 3].forEach.call(["a", "b", "c"], function (item, i, arr) {
console.log(i + ": " + item);
});
// 0: "a"
// 1: "b"
// 2: "c"
따라서 forEach
함수 를 호출하는 빠른 방법을 만들고 this
빈 배열에서 모든 <a>
태그 목록으로 변경 하고 각 <a>
순서에 따라 제공된 함수를 호출합니다.
아래에는 함수형 프로그래밍 시도를 폐기하고 매번 수동 인라인 루핑을 고수하는 기사에 대한 링크가 있습니다.
내가 그 동안 말하고 싶지만 .forEach
그 대응보다 도움이된다, .map(transformer)
, .filter(predicate)
, .reduce(combiner, initialValue)
중 하나에 접근하면서 당신이 정말로 원하는 모두가 외부 세계 (안 배열), N-시간을 수정할 때, 그것은 여전히 용도로 사용 arr[i]
또는 i
.
Motto는 분명히 재능 있고 지식이 풍부한 사람이므로 불일치를 처리하는 방법은 무엇이며, 내가하고있는 일 / 내가 가고있는 곳을 알고 있다고 상상하고 싶습니다 ... 번은 머리 우선 학습)?
대답은 실제로 매우 간단하며 밥 삼촌과 크록 포드 경은 감시로 인해 둘 다 직면 할 것입니다.
그것을 청소하십시오 .
function toArray (arrLike) { // or asArray(), or array(), or *whatever*
return [].slice.call(arrLike);
}
var checked = toArray(checkboxes).filter(isChecked);
checked.forEach(listValues);
자, 당신이 이것을 해야하는지 여부에 대해 의문을 가지고 있다면, 대답은 아마 아닐
것입니다 ... 이 정확한 일은 요즘 고급 기능을 가진 ... 모든 라이브러리에 의해 이루어집니다.
lodash, 밑줄 또는 jQuery를 사용하는 경우 모두 요소 집합을 취하고 n 번 동작을 수행하는 방법이 있습니다.
그런 것을 사용하지 않는다면, 반드시 자신의 것을 쓰십시오.
lib.array = (arrLike, start, end) => [].slice.call(arrLike, start, end);
lib.extend = function (subject) {
var others = lib.array(arguments, 1);
return others.reduce(appendKeys, subject);
};
뿐만 아니라입니다 slice( )
/ array( )
/ 등 도우미 방법은 (그들이 정상적으로)가 배열을 사용하는 것처럼 목록을 사용하기 원하는 사람들을위한 인생을 더 쉽게 만들려고하지만, 상대적으로 근처의 ES6 + 브라우저에서 동작의 고급 스러움을 가지고있는 사람들을위한 Babel에서 미래 또는 "번역"의 언어 기능이 내장되어있어 이러한 유형의 작업이 불필요합니다.
function countArgs (...allArgs) {
return allArgs.length;
}
function logArgs (...allArgs) {
return allArgs.forEach(arg => console.log(arg));
}
function extend (subject, ...others) { /* return ... */ }
var nodeArray = [ ...nodeList1, ...nodeList2 ];
매우 깨끗하고 매우 유용합니다. Rest and Spread 연산자를
찾으십시오 . BabelJS 사이트에서 사용해보십시오. 기술 스택이 올바른 경우 Babel 및 빌드 단계와 함께 프로덕션 환경에서 사용하십시오.
(가) 배열에 배열이 아닌에서 변환 사용할 수하지 않는 좋은 이유가 없습니다 ... 그냥 ... 아무것도하지 않는 코드의 혼란을하지 않습니다 하지만 모든 곳에서, 같은 추한 줄 것을 붙여 넣기.
.call
않는 값 변경 this
사용하고있는 이유는, call
foreach 문으로합니다. foreach는 모습이 좋아하는 경우에 forEach (fn) { var i = 0; var len = this.length; for (; i < length; i += 1) { fn( this[i], i, this ); }
변경하여 다음 this
말함으로써 forEach.call( newArrLike )
이 같은 그 새로운 객체를 사용하는 것을 의미 this
.
.call
의 값은 변경되지 않습니다 this
당신이에 전달 내부 forEach
, .call
의 값 변경 this
대해 forEach의 내부 . 왜 호출하려는 함수로 this
전달되지 않는지에 대해 혼란 스러우면 JavaScript forEach
에서 동작을 찾아야합니다 this
. 부록, 여기에만 적용 (및지도 / 필터 / 감소)으로 행 번째 인수가 forEach
어느 세트 this
함수 내부 arr.forEach(fn, thisInFn)
나 [].forEach.call(arrLike, fn, thisInFn);
또는 사용 .bind
; arr.forEach(fn.bind(thisInFn));
[]
그래서 당신이 할 수있는 것을, 배열로 단지가 방법 및 변경 이 작업을 수행 할 설정합니다. 다음과 같습니다 세트 내부의 검은 마법있을 것을 제외하고 내부 당신이로 전달 된 것 같음이 . .call
.forEach
this
.call
function (thisArg, a, b, c) { var method = this; method(a, b, c); }
this
method
thisArg
이 querySelectorAll
메서드 는 NodeList
배열과 비슷한을 반환 하지만 배열은 아닙니다. 따라서 forEach
메소드를 가지고 있지 않습니다 (어레이 객체는를 통해 상속받습니다 Array.prototype
).
a NodeList
는 배열과 비슷하기 때문에 실제로 배열 메소드가 작동 [].forEach.call
하므로을 사용 하면 마치 할 수있는 것처럼 Array.prototype.forEach
메소드를 호출합니다 .NodeList
yourNodeList.forEach(/*...*/)
빈 배열 리터럴은 확장 버전의 바로 가기 일뿐입니다.
Array.prototype.forEach.call(/*...*/);
[].forEach.call(['a','b'], cb)
하는 ['a','b'].forEach(cb)
일상적인 애플리케이션에서 오버 를 사용 하는 데 이점이 forEach
없습니까? 그 맞습니까?
[].forEach()
:)
var section = document.querySelectorAll(".section"); section.forEach((item)=>{ console.log(item.offsetTop) })
잘 작동
forEach
NodeList의 객체를 배열에 있지만)
다른 답변은이 코드를 잘 설명 했으므로 제안을 추가 할 것입니다.
이것은 단순성과 명확성을 위해 리팩토링되어야하는 코드의 좋은 예입니다. 사용 [].forEach.call()
하거나 Array.prototype.forEach.call()
매번 수행 할 때마다 간단한 기능을 사용하십시오.
function forEach( list, callback ) {
Array.prototype.forEach.call( list, callback );
}
이제 더 복잡하고 모호한 코드 대신이 함수를 호출 할 수 있습니다.
forEach( document.querySelectorAll('a'), function( el ) {
// whatever with the current node
});
이 오래된 질문을 업데이트하고 싶습니다.
[].foreach.call()
최신 브라우저에서 요소를 반복하는 데 사용 하는 이유 는 대부분 끝났습니다. document.querySelectorAll("a").foreach()
직접 사용할 수 있습니다.
NodeList 객체는 일반적으로 Node.childNodes와 같은 속성 및 document.querySelectorAll ()과 같은 메서드에 의해 반환되는 노드 모음입니다.
NodeList는 배열이 아니지만 forEach ()를 사용하여 반복 할 수 있습니다 . Array.from ()을 사용하여 실제 Array로 변환 할 수도 있습니다.
그러나 일부 구형 브라우저는 NodeList.forEach () 또는 Array.from ()을 구현하지 않았습니다. 이는 Array.prototype.forEach ()를 사용하여 회피 할 수 있습니다.이 문서의 예제를 참조하십시오.
한 줄만 추가하십시오.
NodeList.prototype.forEach = HTMLCollection.prototype.forEach = Array.prototype.forEach;
그리고 짜잔!
document.querySelectorAll('a').forEach(function(el) {
// whatever with the current node
});
즐겨 :-)
경고 : NodeList는 글로벌 클래스입니다. 공공 도서관을 작성하는 경우이 권장 사항을 사용하지 마십시오. 그러나 웹 사이트 또는 node.js 앱에서 작업 할 때 자기 효능을 높이는 매우 편리한 방법입니다.
항상 빠르고 더러운 솔루션을 사용합니다. 모범 사례만큼 프로토 타입을 건드리지 않습니다. 물론이를 개선하는 데는 여러 가지 방법이 있지만 아이디어를 얻을 수 있습니다.
const forEach = (array, callback) => {
if (!array || !array.length || !callback) return
for (var i = 0; i < array.length; i++) {
callback(array[i], i);
}
}
forEach(document.querySelectorAll('.a-class'), (item, index) => {
console.log(`Item: ${item}, index: ${index}`);
});
[]
항상 새 배열 new Array()
을 반환하지만 Array
, 사용자가 덮어 쓸 수는 있지만 배열을 반환 할 수 는 있지만 보장 []
할 수는 없습니다. 따라서 이것은의 프로토 타입을 얻는 안전한 방법이며 Array
, 설명 된대로 call
arraylike nodelist (this)에서 함수를 실행하는 데 사용됩니다.
주어진이 값과 개별적으로 제공된 인수로 함수를 호출합니다. mdn
[]
사실 항상 배열을 반환 , window.Array
모든 오래된 브라우저 window.Array.prototype.forEach
에서 무엇이든 덮어 쓸 수 있으므로 무엇이든 덮어 쓸 수 있습니다. 게터 / 세터를 지원하지 않는 브라우저 나 객체 밀봉 / 고정 (고정이 자체 확장 성 문제의 원인)을 지원하지 않는 브라우저의 경우 안전을 보장 할 수 없습니다.
prototype
이나 방법 에 대한 추가 정보를 추가하려면 답변을 편집하십시오 forEach
.
Norguard 는 WHAT [].forEach.call()
가 수행하는 작업 과 James Allardice 가 수행하는 이유를 설명 했습니다. querySelectorAll은 NodeList
forEach 메소드가 없는를 반환하기 때문에 ...
Chrome 51 이상, Firefox 50 이상, Opera 38, Safari 10과 같은 최신 브라우저가 없다면
그렇지 않은 경우 Polyfill을 추가 할 수 있습니다 .
if (window.NodeList && !NodeList.prototype.forEach) {
NodeList.prototype.forEach = function (callback, thisArg) {
thisArg = thisArg || window;
for (var i = 0; i < this.length; i++) {
callback.call(thisArg, this[i], i, this);
}
};
}
이 페이지에 대한 많은 좋은 정보 ( 답변 + 답 + 댓글 참조) 있지만 ) 최근 OP와 동일한 질문이 있었으며 전체 그림을 얻는 데 약간의 파기가 필요했습니다. 여기 짧은 버전이 있습니다 :
목표는 Array
배열과 같은 메소드 를 사용 하는 것입니다.NodeList
그러한 메소드 자체가없는 하는 것입니다.
더 오래된 패턴은를 통해 Array의 메소드를 선택했으며 Function.call()
, 입력하기가 더 짧기 []
보다는 배열 리터럴 ( )을 사용했습니다 Array.prototype
.
[].forEach.call(document.querySelectorAll('a'), a => {})
최신 패턴 (ECMAScript 2015 이후)은 다음을 사용합니다 Array.from()
.
Array.from(document.querySelectorAll('a')).forEach(a => {})