몇 가지 코드 조각을보고 있었고 빈 배열에 forEach가 적용된 노드 목록에서 함수를 호출하는 여러 요소를 발견했습니다.
예를 들어 다음과 같은 것이 있습니다.
[].forEach.call( document.querySelectorAll('a'), function(el) {
// whatever with the current node
});
그러나 그것이 어떻게 작동하는지 이해할 수 없습니다. 누구든지 forEach 앞에서 빈 배열의 동작과 작동 방식을 설명 할 수 있습니까 call
?
답변
[]
배열입니다.
이 배열은 전혀 사용되지 않습니다.
배열을 사용하면과 같은 배열 프로토 타입에 액세스 할 수 있으므로 페이지에 표시 .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);
};
ES6 (ES2015) 이상 업데이트
뿐만 아니라입니다 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 및 빌드 단계와 함께 프로덕션 환경에서 사용하십시오.
(가) 배열에 배열이 아닌에서 변환 사용할 수하지 않는 좋은 이유가 없습니다 … 그냥 … 아무것도하지 않는 코드의 혼란을하지 않습니다 하지만 모든 곳에서, 같은 추한 줄 것을 붙여 넣기.
답변
이 querySelectorAll
메서드 는 NodeList
배열과 비슷한을 반환 하지만 배열은 아닙니다. 따라서 forEach
메소드를 가지고 있지 않습니다 (어레이 객체는를 통해 상속받습니다 Array.prototype
).
a NodeList
는 배열과 비슷하기 때문에 실제로 배열 메소드가 작동 [].forEach.call
하므로을 사용 하면 마치 할 수있는 것처럼 Array.prototype.forEach
메소드를 호출합니다 .NodeList
yourNodeList.forEach(/*...*/)
빈 배열 리터럴은 확장 버전의 바로 가기 일뿐입니다.
Array.prototype.forEach.call(/*...*/);
답변
다른 답변은이 코드를 잘 설명 했으므로 제안을 추가 할 것입니다.
이것은 단순성과 명확성을 위해 리팩토링되어야하는 코드의 좋은 예입니다. 사용 [].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
});
답변
사용하여 더 잘 쓸 수 있습니다
Array.prototype.forEach.call( document.querySelectorAll('a'), function(el) {
});
기능 document.querySelectorAll('a')
은 배열과 유사한 객체를 반환하지만 Array
유형 에서 상속하지는 않습니다 . 그래서 우리 forEach
는 Array.prototype
객체 에서 메소드를 호출합니다.document.querySelectorAll('a')
답변
[].forEach.call( document.querySelectorAll('a'), function(el) {
// whatever with the current node
});
기본적으로 다음과 같습니다.
var arr = document.querySelectorAll('a');
arr.forEach(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 ()를 사용하여 회피 할 수 있습니다.이 문서의 예제를 참조하십시오.