자바 스크립트 forEach 메소드는 어떤 용도로 사용됩니까 (그 맵은 할 수 없음)? 개체 참조되지 않고 this[i]및 i루프의

내가 map과 foreach에서 보는 유일한 차이점 map은 배열을 반환하고 forEach그렇지 않다는 것입니다. 그러나 forEachfunc.call(scope, this[i], i, this);” 메서드 의 마지막 줄도 이해하지 못합니다 . 예를 들어, “없는 this“및 ” scope“동일한 개체 참조되지 않고 this[i]i루프의 현재 값을 참조?

다른 게시물에서 누군가 ” forEach목록의 각 요소를 기반으로 무언가를하고 싶을 때 사용 합니다. 예를 들어 페이지에 항목을 추가 할 수 있습니다. 기본적으로”부작용 “을 원할 때 유용합니다. 부작용이 무엇을 의미하는지 모르겠습니다.

Array.prototype.map = function(fnc) {
    var a = new Array(this.length);
    for (var i = 0; i < this.length; i++) {
        a[i] = fnc(this[i]);
    }
    return a;
}

Array.prototype.forEach = function(func, scope) {
    scope = scope || this;
    for (var i = 0, l = this.length; i < l; i++) {
        func.call(scope, this[i], i, this);
    }
}

마지막으로, 다음과 같이 숫자를 조작하는 것 외에 자바 스크립트에서 이러한 메서드를 실제로 사용하는 것이 있습니까 (데이터베이스를 업데이트하지 않기 때문에) :

alert([1,2,3,4].map(function(x){ return x + 1})); //this is the only example I ever see of map in javascript.

답장을 보내 주셔서 감사합니다.



답변

예제에서 map와 의 근본적인 차이점 은 원래 배열 요소에서 작동하는 반면 명시 적으로 새 배열을 결과로 반환한다는 것입니다.forEachforEachmap

forEach변화하는 선택적하고 – – 각 요소를 원래의 배열에 당신이 몇 가지 조치를 취하고있다. 이 forEach메서드는 각 요소에 대해 제공 한 함수를 실행하지만 아무것도 반환하지 않습니다 ( undefined). 반면, map배열을 살펴보고 각 요소에 함수를 적용한 다음 결과를 새 배열로 내 보냅니다 .

“부작용” forEach은 원래 배열이 변경된다는 것입니다. “부작용 없음” map은 관용적 사용법에서 원래 배열 요소가 변경 되지 않음을 의미합니다 . 새 배열은 원래 배열의 각 요소에 대한 일대일 매핑입니다. 매핑 변환은 제공된 함수입니다.

관련된 데이터베이스가 없다는 사실은 결국 어떤 언어로든 프로그래밍의 본질 중 하나 인 데이터 구조를 조작 할 필요가 없다는 것을 의미하지는 않습니다. 마지막 질문에 관해서는 배열에 숫자뿐만 아니라 객체, 문자열, 함수 등이 포함될 수 있습니다.


답변

두 가지 방법 사이의 주요 차이점은 개념 및 문체입니다 : 당신이 사용하는 forEach당신이 뭔가를 할 때 배열의 각 요소 ( “와”하고는 “부작용”을 의미 인용 포스트, 내가 무슨 생각입니다) , 반면 배열의 각 요소 map복사하고 변환 하려는 경우 (원본을 변경하지 않고) 사용합니다.

둘 다 mapforEach배열의 각 항목에 대해 함수를 호출하고 해당 함수가 사용자 정의되어 있기 때문에 하나를 사용하여 수행 할 수있는 작업이 거의 없습니다. 추악하지만 map배열을 제자리에서 수정하거나 배열 요소로 무언가를 수행하는 데 사용할 수 있습니다.

var a = [{ val: 1 }, { val: 2 }, { val: 3 }];
a.map(function(el) {
    el.val++; // modify element in-place
    alert(el.val); // do something with each element
});
// a now contains [{ val: 2 }, { val: 3 }, { val: 4 }]

그러나 사용하려는 의도는 훨씬 명확하고 명확합니다 forEach.

var a = [{ val: 1 }, { val: 2 }, { val: 3 }];
a.forEach(function(el) {
    el.val++;
    alert(el.val);
});

특히 현실 세계에서 일반적으로 el그렇듯이 사람이 읽을 수있는 유용한 변수 인 경우 :

cats.forEach(function(cat) {
    cat.meow(); // nicer than cats[x].meow()
});

같은 방식 forEach으로 새 배열을 만드는 데 쉽게 사용할 수 있습니다 .

var a = [1,2,3],
    b = [];
a.forEach(function(el) {
    b.push(el+1);
});
// b is now [2,3,4], a is unchanged

그러나 사용하는 것이 더 깨끗합니다 map.

var a = [1,2,3],
    b = a.map(function(el) {
        return el+1;
    });

또한 map새 어레이를 만들기 때문에 필요한 모든 것이 반복 일 때, 특히 대형 어레이의 경우 적어도 약간의 성능 / 메모리 적중이 발생할 수 있습니다. http://jsperf.com/map-foreach를 참조하십시오.

이러한 함수를 사용하려는 이유는 자바 스크립트에서 배열 조작을해야 할 때마다 유용합니다. (브라우저 환경에서 자바 스크립트에 대해 이야기하고 있더라도) 거의 항상 코드에 직접 적지 않은 배열에 액세스하고 있습니다. 페이지의 DOM 요소 배열, AJAX 요청에서 가져온 데이터 또는 사용자가 양식에 입력 한 데이터를 처리 할 수 ​​있습니다. 한 가지 일반적인 예는 외부 API에서 데이터를 가져 오는 것입니다. 여기서 map데이터를 원하는 형식으로 변환하고 forEach사용자에게 표시하기 위해 새 배열을 반복 하는 데 사용할 수 있습니다.


답변

(Ken Redler의) 투표 된 답변은 잘못된 것입니다.

컴퓨터 과학 의 부작용 은 함수 / 메소드의 속성이 글로벌 상태를 변경한다는 것을 의미합니다 [wiki] . 좁은 의미에서 여기에는 인수가 아닌 전역 상태에서 읽는 것도 포함될 수 있습니다. 명령형 또는 OO 프로그래밍에서는 대부분의 경우 부작용이 나타납니다. 그리고 당신은 아마 깨닫지 못하고 그것을 사용하고있을 것입니다.

significiant 간의 차이 forEachmap그 인 map동안, 할당 된 메모리에 저장한다 반환 값 forEach멀리 던진다. 자세한 내용은 emca 사양 을 참조하십시오.

사람들 forEach이 부작용을 원할 때 사용 한다고 말하는 이유 는의 반환 값 forEach이 항상이라는 것 undefined입니다. 부작용이없는 경우 (전역 상태를 변경하지 않음) 함수는 CPU 시간을 낭비하는 것입니다. 최적화 컴파일러는이 코드 블록을 제거하고 최종 값 ( undefined)으로 대체합니다 .

참고로 JavaScript는 부작용에 대한 제한이 없습니다. 내부에서 원래 배열을 계속 수정할 수 있습니다 map.

var a = [1,2,3]; //original
var b = a.map( function(x,i){a[i] = 2*x; return x+1} );
console.log("modified=%j\nnew array=%j",a,b);
// output:
// modified=[2,4,6]
// new array=[2,3,4]


답변

이것은 예상치 못한 대답을 가진 아름다운 질문입니다.

다음은의 공식 설명을Array.prototype.map() 기반으로합니다 .

없다 아무것도forEach() 가 할 수있는 map()캔을하지 않음. 즉, map()A는 엄격한 슈퍼 세트forEach().

map()일반적으로 새 배열을 만드는 데 사용 되지만 현재 배열을 변경 하는데도 사용할 수 있습니다. 다음 예는이를 설명합니다.

var a = [0, 1, 2, 3, 4], mapped = null;
mapped = a.map(function (x) { a[x] = x*x*x; return x*x; });
console.log(mapped); // logs [0, 1, 4, 9, 16]  As expected, these are squares.
console.log(a); // logs [0, 1, 8, 27, 64] These are cubes of the original array!!

위의 예에서, a편리하게되도록 설정 a[i] === ii < a.length. 그럼에도 불구하고의 힘 map(), 특히 호출되는 배열을 변경하는 기능을 보여줍니다 .

참고 1 :
공식 설명 은 호출되는 배열의 길이를map() 변경할 수도 있음을 의미합니다 ! 그러나 나는 이것을 할 (좋은) 이유를 알 수 없습니다.

주 2 :
동안 map()지도의 수퍼 세트이고 forEach(), forEach()하나의 변화를 소정의 배열을 계속하고자 표기가. 이것은 당신의 의도를 명확하게합니다.

이것이 도움이 되었기를 바랍니다.


답변

당신은 사용할 수 map는 것처럼 forEach.

하지만해야 할 일보다 더 많은 일을 할 것입니다.

scope임의의 객체가 될 수 있습니다. 반드시 그런 것은 아닙니다 this.

mapforEach에 대한 실제 용도가 있는지 여부 와 for for또는 while루프 가 실제로 사용되는지 묻습니다 .


답변

이전의 모든 질문이 맞지만 분명히 다른 구분을 할 것입니다. map및 의 사용은 forEach의도를 암시 할 수 있습니다.

나는 map단순히 어떤 방식 으로든 기존 데이터를 변환 할 때 사용 하고 싶습니다 (하지만 원래 데이터가 변경되지 않았는지 확인하고 싶습니다.

forEach컬렉션을 수정할 때 사용하고 싶습니다 .

예를 들어

var b = [{ val: 1 }, { val: 2 }, { val: 3 }];
var c = b.map(function(el) {
    return { val: el.val + 1 }; // modify element in-place
});
console.log(b);
//  [{ val: 1 }, { val: 2 }, { val: 3 }]
console.log(c);
//  [{ val: 3 }, { val: 4 }, { val: 5 }]

내 경험 법칙 map은 항상 소스 목록의 각 요소에 대해 반환 할 새 개체 / 값을 만들고 각 요소 에 대해 일부 작업을 수행하는 대신 반환 할 때 확인하는 것입니다.

기존 목록을 실제로 수정할 필요가없는 한 제자리에서 수정하는 것은 의미가 없으며 기능 / 불변 프로그래밍 스타일에 더 적합합니다.


답변

TL, DR 답변-

map은 항상 다른 배열을 반환합니다.

forEach는 그렇지 않습니다. 그것이 무엇을하는지 결정하는 것은 당신에게 달려 있습니다. 원하는 경우 배열을 반환하고 원하지 않는 경우 다른 작업을 수행합니다.

특정 상황에서는 유연성이 바람직합니다. 당신이 다루는 것이 아니라면 map을 사용하십시오.