LHJ

I'm a FE developer.

13-4. Array 오브젝트(ES3 기준) / 엘리먼트 추가,삭제 매커니즘, delete 연산자

01 Dec 2020 » js_beginner

13-4. Array 오브젝트(ES3 기준) / 엘리먼트 추가,삭제 매커니즘, delete 연산자

엘리먼트 추가

  • 배열에 엘리먼트를 추가하는 방법

    • 삽입할 위치에 인덱스 지정

        var value = [1, 2];
        value[4] = 5;
        console.log(value); // [1, 2, undefined, undefined, 5]
      
      1. 값을 설정하지 않은 추가된 엘리먼트에 undefined 설정
    • 표현식으로 인덱스 지정

        var value = [1, 2];
        value[value.length + 2] = 5;
        console.log(value); // [1, 2, undefined, undefined, 5]
      
      1. 인덱스에 값을 더해 인덱스로 사용

delete 연산자

연산자이므로 배열에 속하는 것은 아닙니다.
하지만 delete와 관련된 것을 한꺼번에 묶어서 다루려고 여기에 작성했습니다.

구분데이터(값)
object매치 대상
프로퍼티삭제할 프로퍼티 이름
인덱스배열의 인덱스
반환삭제 성공: true
실패: false

  • var 변수는 삭제 불가

      var value = 123;
      console.log(delete value); // false
    
    1. var 변수를 삭제할 수 없습니다.
    2. 삭제 실패로 처리하여 false가 반환됩니다.

  • 글로벌 변수는 삭제 가능

      value = "글로벌 변수";
      console.log(delete value);
        
      try {
          console.log(value);
      } catch (e) {
          console.log("존재하지 않음");
      }
      // true
      // 존재하지 않음
    
    1. var 키워드를 사용하지 않은 글로벌 변수는 삭제할 수 있습니다.
    2. 삭제하게 되어 true가 반환됩니다.

    var 키워드를 사용하지 않고 변수를 선언했습니다.
    즉, 글로벌 변수로 선언한 것입니다.

    위의 try catch 문은 value가 삭제되었는지를 확인하는 문입니다.
    console.log(value)에서 value 변수가 없으므로 에러가 납니다.

그런데 위의 코드에서 var value = 123; 이 코드도 사실 글로벌 변수입니다.
왜냐하면 함수 안에 작성하지 않았기 때문입니다.

var value = 123;
value = "글로벌 변수";

둘 다 글로벌 변수입니다.
그러나 var 키워드를 사용하면 변수를 delete 연산자로 삭제할 수 없고,
var 키워드를 사용하지 않은 변수는 delete 연산자로 삭제할 수 있습니다.

따라서 var 키워드를 사용하는 것은 필수라고 할 수 있습니다.
use strict 모드에서는 var 키워드를 선언하지 않고 변수를 선언하면 에러가 납니다.
var 키워드는 변수를 사용할 때 반드시 사용해야된다고 생각하시면 되겠습니다.


  • { name: value } 삭제 방법

    • 삭제할 프로퍼티 이름 작성

        var book = { title: "" };
        console.log(delete book.title); // true
        console.log(book.title); // undefined
      
      1. 오브젝트이름.프로퍼티이름 형태로 작성
      2. 오브젝트에 프로퍼티 이름이 없으면 undefined 반환

      변수가 없을 때는 에러가 나지만, 위와 같이 프로퍼티가 없을 땐 에러가 나지않고 undefined가 출력됩니다.

        var book = { title: "" };
        console.log(delete book); // false
              
        sports = { item: "축구" };
        console.log(delete sports); // true
      
      1. var 변수에 오브젝트를 할당하면 오브젝트 전체를 삭제할 수 없습니다.
      2. var 키워드를 사용하지 않은 변수에 할당하면 삭제할 수 있습니다.
      3. var 키워드를 사용해야하는 또 하나의 목적

      var 키워드를 사용해서 변수를 정의해야 delete 연산자로 삭제할 수 없습니다.

    • ES5에서 삭제 불가 설정 가능
      ES5에서는 삭제 불가를 설정할 수 있습니다.
      이것은 뒤에서 다루겠습니다.


  • 인덱스로 배열의 엘리먼트 삭제

      var value = [1, 2, 3, 4];
      console.log(delete value[1]); // true
      console.log(value.length); // 4
    
    1. 1번 인덱스가 존재하므로 삭제되어 true 반환
    2. 삭제하였으므로 length가 4에서 3으로 줄어야하는데 변하지않고 4가 출력
    3. 이것은 배열 처리 메커니즘 때문입니다.
      다음 페이지에서 살펴봅니다.
      (삭제를 하더라도 length가 변하지 않습니다.)

배열 엘리먼트 삭제 메커니즘

  • 삭제된 인덱스에 undefined 설정

    • 배열을 읽을 때 제외시켜야 합니다.
      var value = [1, 2, 3, 4];
      delete value[1];
      console.log(value); // [1, undefined, 3, 4]
        
      for (var k = 0; k < value.length; k++) {
          console.log(value[k]);
      }
      // 1
      // undefined
      // 3
      // 4
    
    1. 삭제한 인덱스에 undefined가 설정됩니다.
    2. 앞으로 하나씩 당겨서 엘리먼트를 이동하면 처리 시간이 걸리기 때문

왜 삭제를 했는데, 완전히 삭제를 하지않고 undefined를 설정하는 것일까요?

시멘틱 그대로 삭제를하면 심플한데 왜 여기다가 undefined를 설정하냐는 것입니다.

그것은 오래전 배열을 설계할 때, 그 때는 컴퓨터 사양도 안좋았고 배열을 처리하는 알고리즘도 그렇게 좋지 않았습니다.
때문에 처리 속도가 느렸습니다.

배열에 작성할 수 있는 엘리먼트 수는 대략 42억개입니다.
위의 코드에서 2를 삭제하면 3이 2의 자리로 가야되고 4가 3의 자리로 가야합니다.
이것이 일반적인 삭제의 개념이잖아요?

그런데 처음에 배열을 만들던 상황에선 이러한 것이 부담이 되었다는 것입니다.
컴퓨터 사양 때문에요.
맨 앞에껄 지우면 뒤에 거의 42억개를 당겨야하잖아요.
즉, 배열 엘리먼트를 이곳 저곳에서 delete를 했다 - 그러면 컴퓨터가 그걸 따라가지를 못하는 겁니다.

그래서 안되겠다 싶어서 삭제한 자리에다가 undefined를 넣은 것입니다.

그러면 이제는 위와 같이 삭제하고 그 뒤에 undefined를 제거하는 코드가 있어야겠죠?
위 코드에선 for문 안에 그런 처리를 해야됩니다.

하지만 현재는 [1, 2, 3, 4]의 ‘2’를 바로 드러낼수가 있습니다.
메소드를 사용하면 되는건데요, 현재의 상황으로 본다면, 즉 하드웨어 속도, 소프트웨어 속도, 브라우저 상황으로 본다면, 그리고 그렇게 많지 않은 데이터(배열)라면 undefined가 아니라 메소드를 사용해서 삭제를 시키고 뒤에꺼를 앞으로 땡겨도 현재는 그렇게 부담되지 않습니다.

그러면 위에서 말했던 for문 안에 undefined를 걸러내는 코드는 필요가 없게되는거죠.
물론 상황에 따라 다르므로 어떤 것이 반드시 좋다, 나쁘다로 말할 수는 없습니다만, delete로 하는 것보다 메소드를 사용해서 삭제해도 현재는 그렇게 부담이 안된다는 겁니다.