• 카테고리

    질문 & 답변
  • 세부 분야

    프로그래밍 언어

  • 해결 여부

    미해결

forEach() 문 내부에서 delete로 특정 인덱스를 삭제했을 경우

21.04.21 15:21 작성 조회수 1.54k

2

안녕하세요 선생님. 질문이 있어 이렇게 올리게 됐습니다.

var list = [1,2,3];

var fn = function(el, index, all){

if(index === 0){

delete list[2];

};

console.log(el);

};

list.forEach(fn);

위 코드에서 delete list[2]를 사용하고 있습니다. 제가 기억하는바론 splice로 배열에서 엘리먼트 삭제시 완전히 삭제되는반면, delete로 엘리먼트 삭제시 값만 지우고 undefined가 그 자리를 채우는 것으로 기억합니다. 따라서 delete list[2]가 시행되면 value = [1, 2, undefined]가 되고, forEach 구문으로 해당 배열을 나열시

1

2

undefined

가 결과로 출력돼야하는 것 아닌가요??! console.log(value[2]); 를 해보면 undefined가 출력되는데 forEach 문으로 돌렸을 땐 왜 undefined가 출력되지 않는지 궁금합니다! 훌륭한 강의 너무 잘 듣고 있습니다. 감사합니다 :)

답변 2

·

답변을 작성해보세요.

1

forEach 문으로 돌렸을 땐 왜 undefined가 출력되지 않는지 궁금합니다?????

1) forEach는 문이 아니라 method입니다.
2) 2번 인덱스에 undefined가 설정되는 것은 맞습니다.
    왜냐하면 delete list[2]; 실행한 후에도 list.length 값이 3이기 때문입니다.
3) 이것은 forEach() 메소드에서 undefined를 제외시키기 때문입니다.

반면 for 문으로 반복하면 3번 반복하고 undefined가 출력됩니다.
--------------

코드 첫 줄에 debugger를 작성하고 아래 코드의 차이를 비교해보세요. 라인을 이동할 때마다 개발자 도구 창의 오른쪽에서 프로퍼티 값이 변하는 것을 체크해보세요. 중요한 개념이니 시간이 걸리더라도 확실하게 정리해 두세요. window.onload = function (){ ... }을 작성한 것은  오른쪽 창에서 프로퍼티 값을 쉽게 보기 위해서입니다.

window.onload = function(){
  debugger;
  var list = [1,2,3];
  var fn = function(el, index, all){
    if(index === 0){
      delete list[1];
    };
    console.log(el);
  };
  list.forEach(fn);

  for (var index = 0; index < list.length; index++) {
    if(index === 0){
      delete list[1];
    };
    console.log(list[index]);
  };
};

0

yonnani님의 프로필

yonnani

2021.09.04

강사님.
"delete 로 값을 지우면, 해당 인덱스의 값이 undefined로 대체되는 것이 아니라 empty가 되고, empty는 forEach메소드의 순회대상에서 제외된다. 다만, 지워져 empty로 되어버린 부분은 array의 인덱스로 값을 조회 했을 때 undefined를 반환한다."  이렇게 해야 좀 더 정확한 설명이 아닌가요?  제가 잘못 이해하고 있는 부분이 있는지 알려주세요.

질문한 사항이 개념적으로 맞지만, 자바스크립트에서 empty는 개념이며 값이 아닙니다, empty 개념의 값이 undefined입니다. undefined도 값이지만 개념에서 보면 empty입니다. 값이 없으면 length 값이 줄어들며, length 값을 유지하려면 delete한 위치의 인덱스에 값이 있어야 합니다. 

yonnani님의 프로필

yonnani

2021.09.13

이해가 잘 가지 않아 추가 질문 드립니다.

 

length

" length 값을 유지하려면 delete한 위치의 인덱스에 값이 있어야 합니다" 라고 말씀하신 부분이 이해가 가지 않습니다.

아래의 코드 결과를 실제로 콘솔에서 출력해보면 해당 프로퍼티 자체가 아예 존재하지 않는 것으로 나오는데 이걸 어떻게 이해하면 될까요?

var arr = new Array(5).fill(undefined);
delete (arr[2]);
arr.forEach(function(itemindex) {
   console.log(itemindex);
})
console.log(arr);
// (5) [undefined, undefined, empty, undefined, undefined]
// 0: undefined
// 1: undefined
// 3: undefined
// 4: undefined
// length: 5
// [[Prototype]]: Array(0)

말씀하신대로라면, '해당 인덱스'에' '값이' 있어야 하는거 아닌가요?

즉, 2: undefined 라는 값이 나타나야 하지 않나요?

정의되어 있지도 않고 콘솔상에서도 찍히지 않는 값이 있다는걸 어떻게 이해하면 할까요?

 

 

MDN을 찾아보니 "length 속성의 값이 배열에 정의된 원소의 수를 나타내지는 않는다"고 되어 있습니다.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/length

즉, 원소가 존재하지 않을 수 도 있다는 말인데, 강사님은 length가 유지되면 해당 값이 있어야 한다고 반대로 설명하셔서 어떤게 옳은 설명인지 혼란스럽습니다.

 

 

 

forEach

이 질문은 추가질문으로 드리지 않으려고 했는데, empty는 단순히 개념일 뿐이며 해당값이 undefined로 채워져 있다고 설명하시는 것 같아 덧붙입니다.

강사님께서는 루프를 건너띄는 이유가 " forEach() 메소드에서 undefined를 제외시키기 때문" 이라고 하셨네요.

 

일단, 단순한 사실만 놓고 보자면 forEach는 undefined 를 제외하지 않습니다.

https://262.ecma-international.org/5.1/#sec-15.4.4.18

"callbackfn 은 실제로 존재하는 배열의 요소에 대해서만 호출됩니다. 배열의 누락된 요소에 대해서는 호출되지 않습니다." 라고 되어있습니다. (undefined를 제외한다는 설명은 보지 못했습니다.)

 

실제로 코드를 돌려봐도 undefined를 제외하지는 않습니다.

var arr = new Array(5).fill(undefined);
delete (arr[2]);
arr.forEach(function(itemindex) {
   console.log(itemindex);
})
console.log(arr);

// undefined 0
// undefined 1
// undefined 3
// undefined 4

// [undefined, undefined, empty, undefined, undefined];

강사님이 의도하신게 undefined 자체를 제외하는 것이 아니라, "'지워진 인덱스'를 제외하는 것"에 대해 표현을 그렇게 하신 거라면 이해를 하겠습니다. 하지만 뒤에 for문을 예로 든걸 보면, 마치 "for문은 undefined를 제외하지 않지만 forEach는 undefined를 제외시킨다" 라고 설명하시는 것 같습니다.

for 문이 undefined를 출력하는 건, undefined를 건너띄지 않고 정상적으로 출력하는 것이 아니라, 아래처럼 array에 할당되지 않은 인덱스 값에 대해 undefined를 출력하는 현상이 아닌가 해서요.

var list = [];
console.log(list[3]); // undefined

 

empty는 프로퍼티 자체가 존재하지 않음을 콘솔상에서 표현하는 것입니다.

undefined가 실제로 할당되어 있는 것과는 (forEach 상에서의 반복여부 자체가 다르기 때문에) 구분지어서 봐야 하지 않나요?

empty 는 개념일 뿐이며 값은 undefined라는, 마치 동전의 양면같은 걸로 설명을 하시니 어떻게 이해해야 할지 모르겠네요.