[javascript] [] .forEach.call ()은 JavaScript에서 무엇을합니까?

몇 가지 코드 조각을보고 있었고 빈 배열에 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])은 세 가지를 전달합니다.

  1. 배열 내의 요소
  2. 요소의 인덱스 (세번째 요소는 통과합니다 2)
  3. 배열에 대한 참조

마지막으로, .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메소드를 호출합니다 .NodeListyourNodeList.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유형 에서 상속하지는 않습니다 . 그래서 우리 forEachArray.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 ()를 사용하여 회피 할 수 있습니다.이 문서의 예제를 참조하십시오.


답변

빈 배열 forEach의 프로토 타입에는 Function 객체 인 속성 이 있습니다. (빈 배열은 forEach모든 Array객체가 가진 함수에 대한 참조를 얻는 쉬운 방법 일뿐 입니다.) 함수 객체는 차례로 call함수이기도합니다. 함수의 call함수 를 호출 하면 주어진 인수로 함수를 실행합니다. 첫 번째 인수는 this호출 된 함수에 있습니다.

call기능에 대한 설명서는 여기에서 찾을 수 있습니다 . 에 대한 설명서 forEach여기에 있습니다 .