본문으로 바로가기

3.5 배열

배열은 자바스크립트 객체의 특별한 형태

크기를 지정하지 않아도 됨

어떤 위치에 어느 타입의 데이터를 저장하더라도 에러 X


3.5.1 배열 리터럴

자바스크립트에서 새로운 배열을 만드는 데 사용하는 표기법.

배열 리터럴은 대괄호([]) 사용


예제 3-13 배열 리터럴을 통한 배열 생성

// 배열 리터럴을 통한 5개 원소를 가진 배열 생성
var colorArr = ['orange', 'yellow', 'blue', 'green', 'red'];

console.log(colorArr[0]);   // (출력값) orange
console.log(colorArr[1]);   // (출력값) yellow
console.log(colorArr[4]);   // (출력값) red

 

배열 리터럴에서는 각 요소의 값만을 포함

배열 내 위치 인덱스값으로 접근 (0부터 시작)


3.5.2 배열의 요소 생성

객체가 동적으로 프로퍼티를 추가할 수 있듯이, 배열도 동적으로 배열 원소를 추가 가능. 자바스크립트 배열의 경우 값을 순차적으로 넣을 필요 없이 아무 인덱스 위치에나 값을 동적으로 추가 가능.


예제 3-14 배열 요소의 동적 생성

// 빈 배열
var emptyArr = [];
console.log(emptyArr[0]);   // (출력값) undefined

// 배열 요소 동적 생성
emptyArr[0] = 100;
emptyArr[3] = 'eight';
emptyArr[7] = true;

console.log(emptyArr);
    // (출력값) [100, undefined * 2, "eight", undefined * 3, true]
console.log(emptyArr.length);   // (출력값) 8

 

배열 역시 자바스크립트 객체이기 때문에 객체에서도 포함하지 않은 객체의 프로퍼티에 접근한 경우 undefined가 출력된 것과 같이 배열의 경우도 값이 없는 원소에 접근할 경우 undefined 가 출력된다.


배열의 요소는 숫자나 문자열 같은 기본 타입의 값들을 포함해서, 객체나 함수, 배열 등과 같이 자바스크립트의 모든 데이터 타입의 값을 포함할 수 있다.


자바스크립트는 배열의 크기를 현재 배열의 인덱스 중 가장 큰 값을 기준으로 정한다.


값이 할당되지 않은 인덱스의 요소는 undefined 값을 기본으로 가진다.

자바스크립트의 모든 배열은 이러한 length 프로퍼티가 있다. ( 배열의 동작을 이해하는 데 아주 중요)


3.5.3 배열의 length 프로퍼티

length 프로퍼티는 배열의 원소 개수를 나타내지만, 실제로 배열에 존재하는 원소 개수와 일치하지는 않는다.

length 프로퍼티는 배열 내에 가장 큰 인덱스에 1을 더한 값

배열의 가장 큰 인덱스값이 변하면, length 값 또한 자동으로 그에 맞춰 변경됨


예제 3-15 배열의 length 프로퍼티 변경

var arr = [ ];
console.log(arr.length);    // (출력값) 0

arr[0] = 0; // arr.length = 1
arr[1] = 1; // arr.length = 2
arr[2] = 2; // arr.length = 3
arr[100] = 100;
console.log(arr.length);    // (출력값) 101

 

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

배열의 length 프로퍼티는 코드를 통해 명시적으로 값을 변경할 수도 있다.


예제 3-16 배열 length 프로퍼티의 명시적 변경

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

arr.length = 2;
console.log(arr);           // (출력값) [0, 1]
console.log(arr[2]);        // (출력값) undefined

 

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

자바스크립틔의 배열 메서드는 length 프로퍼티를 기반으로 동작한다.

push() : 인수로 넘어온 항목을 배열의 끝에 추가하는 자바스크립트 표준 배열 메서드. 배열의 현재 length 값의 위치에 새로운 원소값 추가.


예제 3-17 push() 메서드와 length 프로퍼티

// arr 배열 생성
var arr = ['zero', 'one', 'two'];

// push() 메서드 호출
arr.push('three');
console.log(arr); // (출력값) ['zero', 'one', 'two', 'three']

// length 값 변경 후, push() 메서드 호출
arr.length = 5;
arr.push('four');
console.log(arr); // (출력값) ['zero', 'one', 'two', undefined, 'four']

 

3.5.4 배열과 객체

자바스크립트에서는 배열 역시 객체다. 하지만 일반 객체와는 약간의 차이가 있다.


예제 3-18 배열과 객체의 유사점과 차이점

// colorsArray 배열
var colorsArray = ['orange', 'yellow', 'green'];
console.log(colorsArray[0]);    // (출력값) orange
console.log(colorsArray[1]);    // (출력값) yellow
console.log(colorsArray[2]);    // (출력값) green

//colorsObj 객체
var colorsObj = {
    '0': 'orange',
    '1': 'yellow',
    '2': 'green'
};
console.log(colorsObj[0]);      // (출력값) orange
console.log(colorsObj[1]);      // (출력값) yellow
console.log(colorsObj[2]);      // (출력값) green

// typeof 연산자 비교
console.log(typeof colorsArray);    // (출력값) object (not array)
console.log(typeof colorsObj);      // (출력값) object

// length 프로퍼티
console.log(colorsArray.length);    // (출력값) 3
console.log(colorsObj.length);      // (출력값) undefined

// 배열 표준 메서드
colorsArray.push('red');    // ['orange', 'yellow', 'green', 'red']
colorsObj.push('red');
    // Uncaught TypeError: Object #<Object> has no method 'push'

 

자바스크립트 엔진이 [] 연산자 내에 숫자가 사용될 경우, 해당 숫자를 자동으로 문자열 형태로 바꿔주기 때문에 colorsObj[0]의 형태로 접근 가능


typeof 연산 결과는 배열의 객체가 모두 object 자바스크립트도 배열을 객체라고 생각한다.


배열과 객체의 차이점

1) 배열은 length 프로퍼티 존재, 객체는 X

2) colorsObj는 배열이 아니므로 앞서 설명한 push()와 같은 표준 배열 메서드 사용 불가

배열과 객체가 자신의 부모인 프로토타입 객체가 서로 다르기 때문

객체 리터럴 방식으로 생성한 객체 : Object.prototype 객체가 프로토타입

배열 : Array.prototype 객체가 프로토타입 push(), pop()과 같은 표준 배열 메서드 포함. Array.prototype 객체의 프로토타입은 Object.prototype 객체


예제 3-19 배열의 프로토타입과 객체의 프로토타입 비교

var emptyArray = [];    // 배열 리터럴을 통한 빈 배열 생성
var emptyObj = {};      // 객체 리터럴을 통한 빈 객체 생성

console.dir(emptyArray.__proto__);      // 배열의 프로토타입(Array.prototype) 출력
console.dir(emptyObj.__proto__);        // 객체의 프로토타입(Object.prototype) 출력

 

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

배열도 자바스크립트 객체 인덱스가 숫자인 배열 원소 이외에도 객체처럼 동적으로 프로퍼티 추가 가능!


예제 3-20 배열의 동적 프로퍼티 생성

// 배열 생성
var arr = ['zero', 'one', 'two'];
console.log(Arr.length);    // (출력값) 3

// 프로퍼티 동적 추가
arr.color = 'blue';
arr.name = 'number_array';
console.log(arr.length);    // (출력값) 3

// 배열 원소 추가
arr[3] = 'red';
console.log(arr.length);    // (출력값) 4

// 배열 객체 출력

console.dir(arr);

 

배열에 동적 프로퍼티가 추가될 경우에는 배열의 length 값이 바뀌지 않는다.

배열의 length 프로퍼티는 배열 원소의 가장 큰 인덱스가 변했을 경우에만 변경됨

배열도 객체처럼 ’key:value' 형태로 배열 원소 및 프로퍼티 등이 있음


3.5.6 배열의 프로퍼티 열거

객체는 for in 문으로 프로퍼티를 열거함

배열도 객체이므로 for in 문을 사용하여 배열 내의 모든 프로퍼티를 열거할 수 있음 but 불필요한 프로퍼티가 출력될 수 있으므로 되도록 for 문 사용


예제 3-21 배열의 프로퍼티 열거

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 연산자 사용 가능


예제 3-22 delete 연산자를 이용한 배열 프로퍼티 삭제

var arr = ['zero', 'one', 'two', 'three'];
delete arr[2];
console.log(arr);           // (출력값) ["zero", "one", undefined * 1, "three"]
console.log(arr.length);    // (출력값) 4

 

delete 연산자로 배열 요소를 삭제해도 배열의 length 값은 변하지 않음 (delete arr[3]을 실행한다고 하더라도) delete 연산자는 해당 요소의 값을 undefined로 설정할 뿐 원소 자체를 삭제하지 않음


보통 배열에서 요소들을 완전히 삭제할 경우 자바스크립트에서는 splice() 배열 메서드 사용


splice() 배열 메서드

splice(start, deleteCount[, item…])

  • start : 배열에서 시작 위치
  • deleteCount : start에서 지정한 시작 위치부터 삭제할 요소의 수
  • item : 삭제할 위치에 추가할 요소

예제 3-23 splice() 메서드를 이용한 배열 프로퍼티 삭제

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

arr.splice(2, 1);   // 2번째 요소를 시작점으로 1개의 원소를 삭제한다.
console.log(arr);           // (출력값) ["zero", "one", "three"]
console.log(arr.length);    // (출력값) 3

 

delete 연산자와는 다르게 배열 요소를 완전히 없앤다. 배열의 요소 개수도 3개

arr[2]는 ‘three’를 가리키게 된다.


3.5.8 Array() 생성자 함수

배열 리터럴도 결국 자바스크립트 기본 제공 Array() 생성자 함수로 배열을 생성하는 과정을 단순화시킨 것

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

(생성자 함수에 대해서는 4장에서 더 자세하게)


Array() 생성자 함수는 호출할 때 인자 개수에 따라 동작이 다르므로 주의

  • 호출할 때 인자가 1개이고, 숫자일 경우 : 호출된 인자를 length로 갖는 빈 배열 생성
  • 그 외 : 호출된 인자를 요소로 갖는 배열 생성

예제 3-24 Array() 생성자 함수를 통한 배열 생성

var foo = new Array(3);
console.log(foo);           // (출력값) [undefined, undefined, undefined]
console.log(foo.length);    // (출력값) 3

var bar = new Array(1, 2, 3);
console.log(bar);           // (출력값) [1, 2, 3]
console.log(bar.length);    // (출력값) 3

 

3.5.9 유사 배열 객체

일반 객체에 length라는 프로퍼티가 있다면 유사 배열 객체(array-like objects)라고 부른다. 이들은 객체임에도 자바스크립트의 표준 배열 메서드를 사용하는 게 가능하다.


예제 3-25 유사 배열 객체의 배열 메서드 호출

var arr = ['bar'];
var obj = {
    name: 'foo',
    length : 1
};

arr.push('baz');
console.log(arr);   // (출력값) ['bar', 'baz']

obj.push('baz');    // (출력값) error

 

유사 배열 객체 obj는 당연히 배열이 아니므로 바로 push() 메서드를 호출할 경우 에러 발생

but 유사 배열 객체의 경우 apply() 메서드를 사용하면 객체지만 표준 배열 메서드를 활용하는 것이 가능.

(4.4.2.4. call과 apply 메서드를 이용한 명시적인 this 바인딩에서 자세히 살펴봄)


예제 3-26 유사 배열 객체에서 apply()를 활용한 배열 메서드 호출

var arr = ['bar'];
var obj = { name : 'foo', length : 1};

arr.push('bax');
console.log(arr);   // (출력값) ['bar', 'baz`]

Array.prototype.push.apply(obj, ['baz']);
console.log(obj);   // (출력값) { '1': 'baz', name: 'foo', length: 2 }

 

4.4.1 arguments 객체나 jQuery 객체가 유사 배열 객체 형태로 되어 있다.


3.6 기본 타입과 표준 메서드

기본 타입은 객체가 아닌데 어떻게 메서드 호출?

기본 타입의 값들에 대해 객체 형태로 메서드를 호출할 경우, 이들 기본값은 메서드 처리 순간에 객체로 변환된 다음 각 타입별 표준 메서드를 호출 메서드 호출이 끝나면 다시 기본값으로 복귀.


예제 3-27 기본 타입 변수에서의 메서드 호출

// 숫자 메서드 호출
var num = 0.5;
console.log(num.toExponential(1));

// 문자열 메서드 호출
console.log("test".charAt(2));

 

toExponential() : 표준 숫자형 메서드. 숫자를 지수 형태의 문자열로 변환. 인자로 받는 값 : 소수점 아래 몇 번째 자리까지 표시할 것인지 지정

charAt() : 문자열에서 인자로 받은 위치에 있는 문자를 반환 (문자열 인덱스는 0부터 시작)


3.7 연산자

3.7.1 + 연산자

더하기 연산(두 연산자가 모두 숫자일 경우)과 문자열 연결 연산(나머지 경우) 수행


예제 3-28 + 연산자 예제

var add1 = 1+2;
var add2 = 'my ' + 'string';
var add3 = 1 + 'string';
var add4 = 'string' + 2;
var add5 = 'true' + false;

console.log(add1);  // (출력값) 3
console.log(add2);  // (출력값) my string
console.log(add3);  // (출력값) 1string
console.log(add4);  // (출력값) string2
console.log(add5);  // (출력값) truefalse

 

3.7.2 typeof 연산자

typeof : 피연산자의 타입을 문자열 형태로 리턴

null과 배열이 object, 함수는 function


숫자 ‘number’

문자열 ‘string’

불린값 ‘boolean’

null ‘object’

undefined ‘undefined’

객체 ‘object’

배열 ‘object’

함수 ‘function’


3.7.3 == (동등) 연산자와 === (일치) 연산자

== : 비교하려는 피연산자의 타입이 다를 경우에 타입 변환을 거친 다음 비교

=== : 피연산자의 타입이 달라도 타입을 변경하지 않고 비교


예제 3-29 == (동등) 연산자와 === (일치) 연산자의 차이점

console.log(1 == '1');  // (출력값) true
console.log(1 === '1'); // (출력값) false

 

이 경우에는 string ‘1’을 숫자 1로 타입 변환했다.

=== 는 두 피연산자가 타입이 다를 경우 바로 false 출력

== 타입 변환에 따른 잘못된 결과를 얻을 수 있으므로 대부분의 자바스크립트 코딩 가이드에서는 추천하지 않음.


3.7.4 !! 연산자

!! : 피연산자를 불린값으로 변환


예제 3-30 !! 연산자 활용을 위한 불린값 변환

console.log(!!0);   // (출력값) false
console.log(!!1);   // (출력값) true
console.log(!!'string');   // (출력값) true
console.log(!!'');   // (출력값) false
console.log(!!null);   // (출력값) false
console.log(!!undefined);   // (출력값) false
console.log(!!{});   // (출력값) true
console.log(!!true);   // (출력값) true
console.log(!!false);   // (출력값) false
console.log(!![1,2,3]);   // (출력값) true
console.log(!![]);      // (출력값) true

 

객체는 값이 비어 있는 빈 객체라도 true 로 변환


#책/인사이드자바스크립트