예:
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자체로 설정되고 thiscallback.One에서은에 포함 된 배열을 생각할 수 있습니다 .forEach()통화가 될 수있는 기본 값 this이지만 그렇지 않은 어떤 이유로,; this될 것입니다 undefined그 두 번째 인수가 제공되지 않은 경우.
(참고 : this콜백이 =>함수 인 경우 위의 내용은 적용되지 않습니다 . 왜냐하면 this그러한 함수가 호출 될 때 아무것도 바인딩되지 않기 때문 입니다.)
또한 Array 프로토 타입에 제공되는 유사한 유틸리티가 모두 있다는 점을 기억하는 것이 중요하며, 최상의 솔루션으로 다른 툴을 선택하는 것이 가장 좋습니다. 당신이있어:
forEach 배열의 모든 항목에 대해 또는 모든 항목에 대해 수행filter 적격 항목 만 포함하는 새 배열을 생성하기 위해;map 기존 배열을 변환하여 일대일 새로운 배열을 만들기 위해;some 배열의 적어도 하나의 요소가 어떤 설명에 맞는지 확인하기 위해;every배열의 모든 항목이 설명과 일치 하는지 확인합니다 .find 배열에서 값을 찾기 위해등등. MDN 링크
part(또는 심지어 oes6 에서도 ) 정의되지 않습니까? 반복되는 가치를 얻는 방법?
part은 undefined배열의 요소가 undefined명시 적 으로 할당 된 경우입니다. 배열의 "빈"슬롯 (값이 할당되지 않은 배열 항목)은 .forEach()대부분의 다른 배열 반복 방법으로 건너 뜁니다 .
.forEach()있는 두 번째 인수가 필요합니다 . 참고 : 이것은 콜백 의 인수가 아닌 인수입니다. thisArgthis.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);
이제 arrarray가 참조 유형 의 배열 인 경우 참조 유형 은 실제 객체 대신 객체의 메모리 위치를 저장하므로 다음 코드가 작동합니다.
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있으며 일반적으로 그렇지 않습니다.
자바 스크립트 값으로 전달하며, 이는 본질적으로 의미하는 것은 partA는 복사 배열의 값.
값을 변경하려면 루프에서 배열 자체에 액세스하십시오.
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'삽입을 먼저 처리해야합니다. 다른 방법은 예상과 다릅니다.