13-4. Array 오브젝트(ES3 기준) / 엘리먼트 추가,삭제 매커니즘, delete 연산자
엘리먼트 추가
배열에 엘리먼트를 추가하는 방법
삽입할 위치에 인덱스 지정
var value = [1, 2]; value[4] = 5; console.log(value); // [1, 2, undefined, undefined, 5]
- 값을 설정하지 않은 추가된 엘리먼트에 undefined 설정
표현식으로 인덱스 지정
var value = [1, 2]; value[value.length + 2] = 5; console.log(value); // [1, 2, undefined, undefined, 5]
- 인덱스에 값을 더해 인덱스로 사용
delete 연산자
연산자이므로 배열에 속하는 것은 아닙니다.
하지만 delete
와 관련된 것을 한꺼번에 묶어서 다루려고 여기에 작성했습니다.
구분 | 데이터(값) |
---|---|
object | 매치 대상 |
프로퍼티 | 삭제할 프로퍼티 이름 |
인덱스 | 배열의 인덱스 |
반환 | 삭제 성공: true 실패: false |
var 변수는 삭제 불가
var value = 123; console.log(delete value); // false
- var 변수를 삭제할 수 없습니다.
- 삭제 실패로 처리하여 false가 반환됩니다.
글로벌 변수는 삭제 가능
value = "글로벌 변수"; console.log(delete value); try { console.log(value); } catch (e) { console.log("존재하지 않음"); } // true // 존재하지 않음
- var 키워드를 사용하지 않은 글로벌 변수는 삭제할 수 있습니다.
- 삭제하게 되어 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
- 오브젝트이름.프로퍼티이름 형태로 작성
- 오브젝트에 프로퍼티 이름이 없으면 undefined 반환
변수가 없을 때는 에러가 나지만, 위와 같이 프로퍼티가 없을 땐 에러가 나지않고 undefined가 출력됩니다.
var book = { title: "책" }; console.log(delete book); // false sports = { item: "축구" }; console.log(delete sports); // true
- var 변수에 오브젝트를 할당하면 오브젝트 전체를 삭제할 수 없습니다.
- var 키워드를 사용하지 않은 변수에 할당하면 삭제할 수 있습니다.
- var 키워드를 사용해야하는 또 하나의 목적
var
키워드를 사용해서 변수를 정의해야delete
연산자로 삭제할 수 없습니다.ES5에서 삭제 불가 설정 가능
ES5에서는 삭제 불가를 설정할 수 있습니다.
이것은 뒤에서 다루겠습니다.
인덱스로 배열의 엘리먼트 삭제
var value = [1, 2, 3, 4]; console.log(delete value[1]); // true console.log(value.length); // 4
- 1번 인덱스가 존재하므로 삭제되어 true 반환
- 삭제하였으므로 length가 4에서 3으로 줄어야하는데 변하지않고 4가 출력
- 이것은 배열 처리 메커니즘 때문입니다.
다음 페이지에서 살펴봅니다.
(삭제를 하더라도 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
- 삭제한 인덱스에 undefined가 설정됩니다.
- 앞으로 하나씩 당겨서 엘리먼트를 이동하면 처리 시간이 걸리기 때문
왜 삭제를 했는데, 완전히 삭제를 하지않고 undefined를 설정하는 것일까요?
시멘틱 그대로 삭제를하면 심플한데 왜 여기다가 undefined
를 설정하냐는 것입니다.
그것은 오래전 배열을 설계할 때, 그 때는 컴퓨터 사양도 안좋았고 배열을 처리하는 알고리즘도 그렇게 좋지 않았습니다.
때문에 처리 속도가 느렸습니다.
배열에 작성할 수 있는 엘리먼트 수는 대략 42억개입니다.
위의 코드에서 2를 삭제하면 3이 2의 자리로 가야되고 4가 3의 자리로 가야합니다.
이것이 일반적인 삭제의 개념이잖아요?
그런데 처음에 배열을 만들던 상황에선 이러한 것이 부담이 되었다는 것입니다.
컴퓨터 사양 때문에요.
맨 앞에껄 지우면 뒤에 거의 42억개를 당겨야하잖아요.
즉, 배열 엘리먼트를 이곳 저곳에서 delete
를 했다 - 그러면 컴퓨터가 그걸 따라가지를 못하는 겁니다.
그래서 안되겠다 싶어서 삭제한 자리에다가 undefined
를 넣은 것입니다.
그러면 이제는 위와 같이 삭제하고 그 뒤에 undefined
를 제거하는 코드가 있어야겠죠?
위 코드에선 for
문 안에 그런 처리를 해야됩니다.
하지만 현재는 [1, 2, 3, 4]
의 ‘2’를 바로 드러낼수가 있습니다.
메소드를 사용하면 되는건데요, 현재의 상황으로 본다면, 즉 하드웨어 속도, 소프트웨어 속도, 브라우저 상황으로 본다면, 그리고 그렇게 많지 않은 데이터(배열)라면 undefined
가 아니라 메소드를 사용해서 삭제를 시키고 뒤에꺼를 앞으로 땡겨도 현재는 그렇게 부담되지 않습니다.
그러면 위에서 말했던 for
문 안에 undefined
를 걸러내는 코드는 필요가 없게되는거죠.
물론 상황에 따라 다르므로 어떤 것이 반드시 좋다, 나쁘다로 말할 수는 없습니다만, delete
로 하는 것보다 메소드를 사용해서 삭제해도 현재는 그렇게 부담이 안된다는 겁니다.