예:
var arr = ["one","two","three"];
arr.forEach(function(part){
part = "four";
return "four";
})
alert(arr);
배열은 여전히 원래 값을 가지고 있습니다. 반복 함수에서 배열의 요소에 액세스 할 수있는 방법이 있습니까?
x=[2,3,4]; x=x.map(n=>n*2); // [4,6,8]
예:
var arr = ["one","two","three"];
arr.forEach(function(part){
part = "four";
return "four";
})
alert(arr);
배열은 여전히 원래 값을 가지고 있습니다. 반복 함수에서 배열의 요소에 액세스 할 수있는 방법이 있습니까?
x=[2,3,4]; x=x.map(n=>n*2); // [4,6,8]
답변:
콜백에는 요소, 인덱스 및 배열 자체가 전달됩니다.
arr.forEach(function(part, index, theArray) {
theArray[index] = "hello world";
});
편집 -주석에서 언급했듯이 .forEach()
함수는 두 번째 인수를 취할 수 this
있으며 콜백에 대한 각 호출 의 값으로 사용됩니다 .
arr.forEach(function(part, index) {
this[index] = "hello world";
}, arr); // use arr as this
그 두 번째 예제 프로그램 arr
자체로 설정되고 this
callback.One에서은에 포함 된 배열을 생각할 수 있습니다 .forEach()
통화가 될 수있는 기본 값 this
이지만 그렇지 않은 어떤 이유로,; this
될 것입니다 undefined
그 두 번째 인수가 제공되지 않은 경우.
(참고 : this
콜백이 =>
함수 인 경우 위의 내용은 적용되지 않습니다 . 왜냐하면 this
그러한 함수가 호출 될 때 아무것도 바인딩되지 않기 때문 입니다.)
또한 Array 프로토 타입에 제공되는 유사한 유틸리티가 모두 있다는 점을 기억하는 것이 중요하며, 최상의 솔루션으로 다른 툴을 선택하는 것이 가장 좋습니다. 당신이있어:
forEach
배열의 모든 항목에 대해 또는 모든 항목에 대해 수행filter
적격 항목 만 포함하는 새 배열을 생성하기 위해;map
기존 배열을 변환하여 일대일 새로운 배열을 만들기 위해;some
배열의 적어도 하나의 요소가 어떤 설명에 맞는지 확인하기 위해;every
배열의 모든 항목이 설명과 일치 하는지 확인합니다 .find
배열에서 값을 찾기 위해등등. MDN 링크
part
(또는 심지어 o
es6 에서도 ) 정의되지 않습니까? 반복되는 가치를 얻는 방법?
part
은 undefined
배열의 요소가 undefined
명시 적 으로 할당 된 경우입니다. 배열의 "빈"슬롯 (값이 할당되지 않은 배열 항목)은 .forEach()
대부분의 다른 배열 반복 방법으로 건너 뜁니다 .
.forEach()
있는 두 번째 인수가 필요합니다 . 참고 : 이것은 콜백 의 인수가 아닌 인수입니다. thisArg
this
.forEach
this
전달 된 두 번째 인수로 를 사용하려면 ES6의 화살표 함수를 .forEach()
사용하면 컨텍스트가 바인딩되지 않으므로 구문을 사용하여 콜백 함수를 전달해야합니다 . function()
() => {}
의합시다 시도 간단하게하고 실제로 작동하는 방법을 논의하기 위해. 변수 유형 및 함수 매개 변수와 관련이 있습니다.
우리가 이야기하는 코드는 다음과 같습니다.
var arr = ["one","two","three"];
arr.forEach(function(part) {
part = "four";
return "four";
})
alert(arr);
먼저 Array.prototype.forEach ()에 대해 읽어야합니다.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
둘째, JavaScript의 값 유형에 대해 간단히 이야기하겠습니다.
프리미티브 (정의되지 않은, null, 문자열, 부울, 숫자)는 실제 값을 저장합니다.
전의: var x = 5;
참조 유형 (사용자 정의 객체)은 객체의 메모리 위치를 저장합니다.
전의: var xObj = { x : 5 };
셋째, 함수 매개 변수 작동 방식
함수에서 매개 변수는 항상 값으로 전달됩니다.
하므로 arr
문자열의 배열이고, 그 배열의 프리미티브 들이 값에 의해 저장되는 수단 개체.
따라서 위의 코드 foreach는 ()가 반복마다 있음이 수단 part
과 동일한 값과 같은 arr[index]
, 하지만 동일한 개체 .
part = "four";
part
변수 가 변경 되지만 arr
홀로 남겨 집니다.
다음 코드는 원하는 값을 변경합니다.
var arr = ["one","two","three"];
arr.forEach(function(part, index) {
arr[index] = "four";
});
alert(arr);
이제 arr
array가 참조 유형 의 배열 인 경우 참조 유형 은 실제 객체 대신 객체의 메모리 위치를 저장하므로 다음 코드가 작동합니다.
var arr = [{ num : "one" }, { num : "two"}, { num : "three"}];
arr.forEach(function(part, index) {
// part and arr[index] point to the same object
// so changing the object that part points to changes the object that arr[index] points to
part.num = "four";
});
alert(arr[0].num);
alert(arr[1].num);
alert(arr[2].num);
다음 part
은 객체를 arr
단독으로 저장 한 채로 새 객체를 가리 키도록 변경할 수 있음을 보여줍니다 .
var arr = [{ num : "one" }, { num : "two"}, { num : "three"}];
arr.forEach(function(part, index) {
// the following will not change the object that arr[index] points to because part now points at a new object
part = 5;
});
alert(arr[0].num);
alert(arr[1].num);
alert(arr[2].num);
In functions, parameters are always passed by value.
두 번째 예는 어떻습니까?
배열 : [1, 2, 3, 4]
결과 :["foo1", "foo2", "foo3", "foo4"]
Array.prototype.map()
원래 배열 유지const originalArr = ["Iron", "Super", "Ant", "Aqua"];
const modifiedArr = originalArr.map(name => `${name}man`);
console.log( "Original: %s", originalArr );
console.log( "Modified: %s", modifiedArr );
Array.prototype.forEach()
원래 배열 재정의const originalArr = ["Iron", "Super", "Ant", "Aqua"];
originalArr.forEach((name, index) => originalArr[index] = `${name}man`);
console.log( "Overridden: %s", originalArr );
let arr1 = ["1", 2, 3, 4]; arr1.map(function(v) { return "foo"+ v; }); console.log( arr );
Array.prototype.map () 절대로 원래 배열을 수정하지 마십시오.
map
확실히 배열을 변경할 수 forEach
있으며 일반적으로 그렇지 않습니다.
자바 스크립트 값으로 전달하며, 이는 본질적으로 의미하는 것은 part
A는 복사 배열의 값.
값을 변경하려면 루프에서 배열 자체에 액세스하십시오.
arr[index] = 'new value';
part
변수가 포인터가 아니라 값이라는 것이 옳더라도-복사 여부 에 따라 다릅니다.
.forEach 함수는 콜백 함수 (eachelement, elementIndex)를 가질 수 있습니다. 따라서 기본적으로해야 할 일은 다음과 같습니다.
arr.forEach(function(element,index){
arr[index] = "four"; //set the value
});
console.log(arr); //the array has been overwritten.
또는 원래 배열을 유지하려면 위의 프로세스를 수행하기 전에 사본을 만들 수 있습니다. 복사하려면 다음을 사용하십시오.
var copy = arr.slice();
map()
대신을 사용하십시오 forEach()
. map()
소스 배열을 반복하고 원본의 [수정 된] 사본을 포함하는 새 배열을 반환합니다. 소스 배열은 변경되지 않습니다.
Array 객체 메서드를 사용하면 기본 for 루프와 비교하여 Array 내용을 수정할 수 있지만 이러한 메서드에는 중요한 기능이 하나 없습니다. 실행시 인덱스를 수정할 수 없습니다.
예를 들어 현재 요소를 제거하고 동일한 배열 내의 다른 인덱스 위치에 배치하면 쉽게 수행 할 수 있습니다. 현재 요소를 이전 위치로 이동하면 다음 반복에서 문제가 발생하지 않으며 마치 아무것도하지 않은 것처럼 다음 항목이 동일하게됩니다.
인덱스가 5까지 카운트되면 인덱스 위치 5에서 항목을 인덱스 위치 2로 이동하는이 코드를 고려하십시오.
var ar = [0,1,2,3,4,5,6,7,8,9];
ar.forEach((e,i,a) => {
i == 5 && a.splice(2,0,a.splice(i,1)[0])
console.log(i,e);
}); // 0 0 - 1 1 - 2 2 - 3 3 - 4 4 - 5 5 - 6 6 - 7 7 - 8 8 - 9 9
그러나 현재 요소를 현재 색인 위치 너머로 이동하면 약간 지저분 해집니다. 그런 다음 바로 다음 항목이 이동 된 항목 위치로 이동하고 다음 반복에서는이를 보거나 평가할 수 없습니다.
인덱스가 5까지 카운트되면 인덱스 위치 5에서 항목을 인덱스 위치 7로 이동하는이 코드를 고려하십시오.
var a = [0,1,2,3,4,5,6,7,8,9];
a.forEach((e,i,a) => {
i == 5 && a.splice(7,0,a.splice(i,1)[0])
console.log(i,e);
}); // 0 0 - 1 1 - 2 2 - 3 3 - 4 4 - 5 5 - 6 7 - 7 5 - 8 8 - 9 9
그래서 우리는 루프에서 6을 결코 만나지 않았습니다. 일반적으로 for 루프에서는 배열 항목을 앞으로 이동할 때 인덱스가 다음 실행에서 동일한 위치에 유지되고 제거 된 항목 위치로 이동 된 항목을 평가할 수 있도록 인덱스 값을 감소시킬 것으로 예상됩니다. 배열 방법으로는 불가능합니다. 색인을 변경할 수 없습니다. 다음 코드를 확인하십시오
var a = [0,1,2,3,4,5,6,7,8,9];
a.forEach((e,i,a) => {
i == 5 && (a.splice(7,0,a.splice(i,1)[0]), i--);
console.log(i,e);
}); // 0 0 - 1 1 - 2 2 - 3 3 - 4 4 - 4 5 - 6 7 - 7 5 - 8 8 - 9 9
우리가 감소 i
하면 5에서 6까지 계속되지 않고 왼쪽에서 계속됩니다.
따라서 이것을 명심하십시오.
복사본을 반복하기 위해 slice ()의 zhujy_8833 제안을 확장하여 색인을 변경하는 요소를 완전히 추가하거나 삭제하려면 이미 삭제하거나 추가 한 요소의 수를 세고 그에 따라 색인을 변경하십시오. 예를 들어, 요소를 삭제하려면 다음을 수행하십시오.
let values = ["A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8"];
let count = 0;
values.slice().forEach((value, index) => {
if (value === "A2" || value === "A5") {
values.splice(index - count++, 1);
};
});
console.log(values);
// Expected: [ 'A0', 'A1', 'A3', 'A4', 'A6', 'A7', 'A8' ]
전에 요소를 삽입하려면
if (value === "A0" || value === "A6" || value === "A8") {
values.splice(index - count--, 0, 'newVal');
};
// Expected: ['newVal', A0, 'A1', 'A2', 'A3', 'A4', 'A5', 'newVal', 'A6', 'A7', 'newVal', 'A8' ]
다음에 요소를 삽입하려면
if (value === "A0" || value === "A6" || value === "A8") {
values.splice(index - --count, 0, 'newVal');
};
// Expected: ['A0', 'newVal', 'A1', 'A2', 'A3', 'A4', 'A5', 'A6', 'newVal', 'A7', 'A8', 'newVal']
요소를 바꾸려면 :
if (value === "A3" || value === "A4" || value === "A7") {
values.splice(index, 1, 'newVal');
};
// Expected: [ 'A0', 'A1', 'A2', 'newVal', 'newVal', 'A5', 'A6', 'newVal', 'A8' ]
참고 : 'before'및 'after'삽입을 모두 구현하는 경우 코드는 'before'삽입을 먼저 처리해야합니다. 다른 방법은 예상과 다릅니다.