[ch3.5] 자바스크립트의 배열

Maru·2022년 7월 20일
0
post-thumbnail

이 글은 저서 [인사이드 자바스크립트]를 공부하고자 작성되었으며, 핵심 개념과 새롭게 알게 된 내용을 위주로 기록하였습니다.

이 장에서 다루는 내용

  • 참조 데이터 타입 : 배열
  • 주의해야 할 연산자

3.5 배열


배열은 js 객체의 특별한 형태다.

  • c와 자바와 달리, 굳이 크기를 지정하지 않아도 되며,
  • 어느 위치에 어느 타입의 데이터를 저장해도 에러가 생기지 않는다

3.5.1 배열 리터럴

배열 리터럴이란, js에서 새로운 배열을 만드는데 사용하는 표기법이다.
배열 리터럴은 대괄호 [ ] 를 사용한다.


var colorArr = ['hello','hi'];
console.log(colorArr[1]) 

  • 배열 리터럴에선 각 요소의 값만을 포함한다.
  • 원소에 접근 할 땐 배열 내 위치 인덱스값으로 접근한다.
  • 배열 원소의 인덱스는 0부터 시작한다.

3.5.2 배열의 요소 생성

배열도 동적으로 배열 원소를 추가할 수 있다.

특히 js는 배열 원소 값을 순차적으로 넣을 필요 없이 아무 인덱스 위치에나 값을 동적으로 추가할 수 있다.


var emptyArr = []; // 빈 배열 생성 
console.log(emptyArr[0]) // undefinded

emptyArr[0] = 1;
emptyArr[3] = 2;

console.log(emptyArr) // [1, undefined * 2, 2]
console.log(emptyArr.length); // 4

주의 할 점

js는 배열의 크기를 현재 배열의 인덱스 중 가장 큰 값을 기준으로 정한다.
위 예제에서도 가장 큰 인덱스가 3이므로, 0부터 3까지 총 4개인 것이다.


3.5.3 배열의 length 프로퍼티


js의 모든 배열은 length 프로퍼티가 있다. length 프로퍼티는 배열의 원소 개수를 나타내지만, 실제로 배열에 존재하는 원소 개수과 일치하는 것은 아니다.

  • 즉, lenght 프로퍼티는 배열 내에 가장 큰 인덱스에 1을 더한 값이다.

  • 배열 리터럴로 생성한 arr은 최초에는 빈 배열이다. length 프로퍼티의 값도 0이다. arr[100]에 원소 값을 저장하면, length 프로퍼티는 101이 된다.

주의

하지만 실제 메모리는 length 크기처럼 할당되지는 않는다.

lenght 프로퍼티의 명시적 변경

length 프로퍼티는 코드를 통해 명시적으로 변경할 수 있다.

var arr = [0,1,2];
arr.length = 5;
console.log(arr) // [0,1,2,undefined * 5]

arr.length = 2;
console.log(arr) // [0,1]
  • length 값이 변경되면, length가 가리키는 위치가 변경된다.
  • length 값을 실제 원소 수 보다 작게 변경하면, length값을 벗어나는 원소들은 실제로 삭제된다.

3.5.3.1 배열의 표준 메서드와 length 프로퍼티


js는 배열에 사용 가능한 다양한 표준 메서드를 제공한다.
이런 배열 메서드는 length 프로퍼티를 기반으로 동작한다.

예시

  • push() 메서드는 인자로 넘어온 항목을 배열의 끝에 추가하는 js 표준 배열 메서드다. 현재 length 값의 위치에 새로운 원소값을 추가한다. length는 '배열 맨 마지막 원소의 인덱스 + 1'이므로, length가 가리키는 곳에 새 원소를 추가하는 것이다.
var arr = [0,1,2];
arr.length = 4;
console.log(arr) // [0,1,2,undefined]
arr.push(3) 
console.log(arr) // [0,1,2,undefined ,3]

3.5.4 배열과 객체


js에선 배열도 객체다. 하지만 일반 객체와는 차이가 있다.


var arr = ['one','two','three'];

var obj = {
    
    '0' : 'one',
    '1' : 'two',
    '2' : 'three',
}

console.log(obj[0]); // one

console.log(typeof arr) // Object 
console.log(typeof obj) // Object

console.log(arr.length) // 3 
console.log(obj.length) // undefined

arr.push('four')
obj.push('four') // 오류 !! 

1) 배열과 객체 생성

  • 대괄호 리터럴을 사용해 객체의 프로퍼티에 접근 할 때, 프로퍼티의 속성을 "문자열 형태"로 적어야한다.
    하지만 위 예제에선 그냥 숫자 형태로 작성했다.
  • 이것은 js 엔진이 [] 연산자 내에 숫자가 사용될 경우 해당 숫자를 자동으로 문자열 형태로 바꾸기 때문이다.

2) typeof 연산자

배열과 객체 모두 typeof 연산 결과 object가 출력된다.

3) length 프로퍼티 존재 유무

  • 객체는 length 프로퍼티가 존재하지 않는다.

4) 배열 표준 메서드 호출 여부

객체는 배열 표준 메서드를 사용할 수 없다.

  • 배열과 객체가 자신의 부모인 프로토타입 객체가 서로 다르기 때문이다.
  • 객체 리터럴 방식으로 생성된 객체의 경우, 객체 표준 메서드를 저장하고 있는 Object.prototype 객체가 프로토타입이다.
  • 배열은 Array.prototype 객체가 프로토타입이 된다. 이 객체는 push()와 pop()와 같은 표준 메서드를 포함한다. 그리고 Array.protorype의 프로토타입은 Object.prototype 객체다.

    배열은 Array.protorype에 포함된 메서드와 Object.prototype에 정의된 메서드를 모두 사용할 수 있다.

배열의 프로토타입

객체의 프로토타입

-> 이미지 출처


3.5.5 배열의 프로퍼티 동적 생성


> 배열도 객체이므로, 객체처럼 배열의 프로퍼티를 동적으로 생성할 수 있다.
var arr = [1,2,3];
arr.color = 'red';

console.log(arr.length) // 3 

주의 할 점

배열에 동적으로 프로퍼티를 추가해도, length 프로퍼티 값은 변하기 않는다.
배열의 lenght 프로퍼티는 배열 원소의 가장 큰 인덱스가 변했을 경우만 변경된다.

  • 크롬 브라우저에서 console.dir(arr)를 실행하면 arr 배열의 모든 프로퍼티를 확인 할 수 있다.

결국 배열도 객체처럼 'key : value'의 형태로 배열 원소 및 프로퍼티 등이 있는 것을 알 수 있다.


3.5.6 배열의 프로퍼티 열거


> 객체는 for in 을 사용해 프로퍼티를 열거할 수 있다. 배열도 for in을 사용할 수는 있지만, 불필요한 프로퍼티가 출력될 수 있으므로 for문을 사용하는 것이 좋다.
for ( var prop in arr) {
console.log(prop, arr[prop]);
}

for (var i=0; i<arr.length; i++) {
console.log(i, arr[i]);
}


3.5.7 배열 요소 삭제


> 배열도 객체이므로, 배열의 요소나 프로퍼티를 삭제할 때 delete 연산자를 사용할 수 있다.

주의할 점

delete 연산자로 배열의 특정 요소를 삭제해도, 배열의 length 값은 변하지 않는다.

  • delete는 해당 요소의 값을 undefined로 변경할 뿐, 원소 자체를 삭제하지 못하지 때문이다.
  • 원소 자체를 완전히 삭제하려면 splice() 배열 메서드를 사용해야한다.

splice() 배열 메서드

  • splice(start, deleteCount, item...)
  • start : 시작 위치
  • deleteCount : 삭제할 요소 개수
  • item : 삭제할 위치에 추가할 요소
var arr = [1,2,3];

delete arr[0]; 
console.log(arr, arr.length);

arr.splice(0,1);
console.log(arr,arr.length);


3.5.8 Array() 생성자 함수


배열은 일반적으로 배열 리터털로 생성하지만, 이것도 결국 js 기본 제공 Array() 생성자 함수로 배열을 생성하는 과정을 단순화시킨 것이다.

일부 js 개발자들은 Array() 생성자 함수로 배열을 생성하는 코드를 작성하기도 하므로 간단히 알아두기만 하면 좋다.

생성자 함수로 객체를 생성할 때는 반드시 new 연산자를 같이 써야한다.

Array() 생성자 함수

호출 인자 수에 따라 동작이 다르므로 주의해야한다.

  • 인자가 1개이고, 숫자일 경우 : 호출 인자를 lenght로 같은 빈배열 생성
  • 그 외 : 호출된 인자를 요소로 같은 배열 생성

3.5.9 유사 배열 객체


length 프로퍼티를 가진 객체를 "유사 배열 객체"라 한다.
유사 배열 객체는 js의 표준 배열 메서드를 사용하는게 가능하다.

객체에 원소 push 하는 방법

  • 유사 배열 객체에 표준 배열 메서드를 사용할 수 있다고해서 직접적으로 push 함수 사용이 가능한 것은 아니다.
var arr = ['foo'];
var obj = {
	name : 'foo',
  	length : 1
};

arr.push('hello');
console.log(arr); // ['foo','hello']

obj.push('hello'); // error !!
  • 위 예제에서 obj는 유사 배열 객체지, 배열은 아니므로 바로 push 함수를 호출할 경우 에러가 발생한다.

  • 하지만 4장에서 배울 apply() 메서드를 사용하면 객체지만 표준 배열 메서드를 활용할 수 있다.
    (자세한 것은 4.4.2.4 call과 apply 메서드를 이용한 명시적인 this 바인딩에서 자세히 알아보자 ->)

var obj = {
	name : 'foo',
  	length : 1
};


Array.prototype.push.apply(obj, ['baz']);
console.log(obj) // ['1':'baz', name : 'foo',
  	length : 2]
  • 새로운 프로퍼티 '1'이 생성되고 원소 'baz'가 추가됐다. 또한length 프로퍼티도 2로 증가한 것을 볼 수 있다.
profile
함께 일하고 싶은 개발자

0개의 댓글