ID : 2401271952
Tag : #javascript
배열
자바스크립트에서의 배열은 다른 프로그래밍 언어와는 다르게 조금 특별한 형태이다.
가장 먼저 보이는 차이점은 다른 객체지향 언어인 C#이나 자바에서는 자료형과 크기를 먼저 지정한 후 배열을 사용해야 하는데 자바스크립트에서는 굳이 크기를 지정하지 않고 어떤 위치에서나 어느 타입의 데이터를 크기 지정없이 생성을 할 수 있다.
1. 배열 리터럴
객체 리터럴처럼 배열도 특정 리터럴을 통해 배열을 생성 할 수 있다.
객체 리터럴의 경우 중괄호 ‘ { } ’ 를 이용한 표기법이 있지만, 배열의 리터럴의 경우에는 대괄호 ‘ [ ] ’ 를 사용한다.
따라서 객체가 프로퍼트의 이름 을 통해 해당 프로퍼티에 접근을 한다면, 배열은 배 열 내 위치 인덱스 값을 넣어서 접근한다.
2. 배열의 요소와 특징
객체가 동적으로 프로퍼티를 추가할 수 있듯이, 배열도 동적으로 배열 원소를 추가 할 수 있다. 따라서 다른 객체지향 언어와는 다르게 값을 아무 위치에나 동적으로 추가하여 사용이 가능하다. 아래의 실험을 통해 특징을 살펴보자
const emptyArr = [];
console.log(emptyArr[0]); // OUT : undefined
emptyArr[0] = 100;
emptyArr[3] = ‘hello’;
emptyArr[7] = true;
console.log(emptyArr); // OUT : [100, undefined, undefined, “string”, undefined, undefined, undefined, true]
console.log(emptyArr.lenth); // OUT : 8
여기서 특이한 점은 3개의 요소 값만을 할당했지만, console.log(emptyArr.length) 의 출력 결과르 보면, 8개의 배열 요소 값이 출력된다는 것이다. 이것은 자바스크립트가 배열의 크기를 현재 배열의 인덱스 중 가장 큰 값을 기준으로 정하기 때문이다.
따라서 현재 배열의 인덱스 중 가장 큰 값은 7이므로 총 배열의 요소 개수는 인덱스 0부터 7까지 총 8개가 되는 것이다.
다른 특징으로는 값이 할당되지 않은 인덱스의 요소는 undefined 값을 기본으로 가진다. 그리고 모든 배열은 length 프로퍼티를 기본으로 가지고 있다.
3. 배열의 length 프로퍼티
위의 예제에서 보이는 것 처럼 emptyArr.length의 값은 배열 내에 가장 큰 익덱스에 1을 더한 값이다. 만약 인덱스의 값이 100이 들어간 배열이 있다면 그 배열의 length값은 101이 된다.
배열의 length 프로퍼티는 명시적으로도 변경이 가능한데 아래의 실험에서 확인을 해보도록 하자.
const arr = [0, 1, 2];
console.log(arr.length); // OUT : 3
arr.length = 5;
console.log(arr); // OUT : [0, 1, 2, undefined, undefined];
arr.length = 2;
console.log(arr); // OUT : [0, 1];
console.log(arr[2]) // OUT : undefined
4. 배열 표준 메서드와 length 프로퍼티
자바스크립트는 배열에서 사용 가능한 다양한 표준 메서드를 제공한다.
이러한 배열 메서드는 length 프로퍼티를 기반으로 동작하고 있다.
push() 메서드는 인수로 넘어온 항목을 배열의 끝에 추가하는 자바스크립트 표준 배열 메서드다. 이 메서드는 length 값의 위치에 새로운 원소값을 추가한다. 즉, 인덱스+1의 자리에 값을 저장하기 때문에 결과적으로 배열의 가장 마지막 부분에 값을 추가하는 것이다.
5. 배열과 객체
자바스크립트에서는 배열도 객체이다.
하지만 배열은 일반 객체와는 차이점이 있다. 아래의 실험을 통해 배열과 객체가 서로 어떻게 차이가 나는지 확인해보자.
const numbersArr = [1, 2, 3];
const numbersObj = {
'1' : 'one',
2 : 'two',
3 : 'three',
};
console.log(numbersArr[1]); // OUT : 1
console.log(numbersObj[1]); // OUT : one
console.log(numbersArr.length); // OUT : 3
console.log(numbersObj.length); // OUT : undefined
numbersArr.push(4);
numbersObj.push(4); // OUT : Uncaught TypeError : Object #<Object> has no method ‘push’
- numbersObj에서 ‘1’을 출력할때 문자형 ’1‘ 이 아닌 숫자형 1 을 이용해 출력을 했다. 오류가 출력될것 같았지만 정상적으로 ‘one’이 출력되었다. 이는 자바스크립트에서 대괄호 ’ [ ] ‘ 연산자 내에서 숫자나 문자가 사용될 경우 자동으로 형변환을 통해 같은 key를 찾아주기 때문이다.
- 배열 numbersArr 와 numbersObj는 근본적인 차이가 있다. 우선 numbersObj는 객체이므로 length프로퍼티와 push()메서드 같은 기본 배열 메서드가 존재하지 않는다. 따라서 위와 같은 오류메시지가 표시되는 것이다. 이것은. Object.prototype 객체가 프로토타입이다. 반면에 배열의 경우 Array.prototype 객체가 부모인 객체인 프로토타입이 된다. Array.prototype 객체는 배열에서 사용할 push(), pop() 같은 표준 메서드를 포함하고 있다. 그렇다고 배열과 객체의 근본이 다르다고 할 수 없는게 Array.prototype 또한 Object.prototype으로 부터 상속을 받았기 때문에 배열에서도 Object.prototype의 표준 메서드들을 모두 사용할 수 있다. 아래의 실험을 통해 확인해보자.
const arr = ['zero','one','two'];
console.log(arr.length); // OUT : 3
arr.name = 'kjw';
arr.color = 'yellow';
console.log(arr.length); // OUT : 3
arr[3] = 'three';
console.log(arr.length); // OUT : 4
console.dir(arr); // OUT : ['zero','one','two','three',name:'kjw',color:'yello']
이 실험에서 arr 배열에 동적으로 color 와 name 프로퍼티를 추가했다.
여기서 주목할 점은 이렇게 동적 프로퍼티를 추가했음에도 length의 값이 3으로 바뀌지 않는다는 것이다. 그리고 다시 arr[3]에 원소를 추가했을 때 length 값이 4로 바뀌는 것을 확인할 수 있다. 그리고 console.dir(arr)를 통해 모든 프로퍼티를 출력한 결과 결국 배열도 객체처럼 key : value 형태로 배열 원소 및 프로퍼티 등이 있음을 알 수 있다.
6. Array() 생성자 함수
여태까지 배열을 생성할때 리터럴 방식으로 생성하였다. 하지만 배열 리터럴도 결국 자바스크립트에서 기본으로 제공하는 Array() 생성자 함수 로 배열을 생성하는 과정을 단순화시킨 것이다. 만약 Array() 나 다른 생성자 함수로 배열과 같은 객체를 생성할 때는 반드시 new 연산자를 같이 써야 한다는 것을 기억해야 한다. 그리고 Array() 생성자 함수로 호출하여 생성할 때 인자에 개수에 따라 동작이 달라지므로 주의해야 한다.
아래의 실험을 통해 Array() 생성자의 인수에 따라 동작이 어떻게 달라지는지 확인해보자.
const arr1 = new Array(3);
console.log(arr1); // OUT : [undefined, undefined, undefine]
console.log(arr1.length); // OUT : 3
const arr2 = new Array(1,2,3);
console.log(arr2); // OUT : [1, 2, 3]
console.log(arr2.length) // OUT : 3
7. 유사 배열 객체
자바스크립트에서 배열이 갖는 특징중 하나로 length의 존재 유무가 있었다.
하지만 자바스크립트에서는 배열이 아닌 객체에서도 length를 적용하여 마치 배열과 유사해 보이는 유사 배열 객체 를 사용할 수 있다. 유사 배열 객체는 apply() 메서드를 사용하면 객체지만 표준 배열 메서드를 활용하는 것이 가능하다. 아래 실험을 통해 apply() 메서드를 적용하여 push() 메서드를 활용하는 모습을 확인해보자.
const arr = ['one'];
const obj = { index : 'one', length : 1};
arr.push('two');
console.log(arr); // OUT : ['one','two']
Array.prototype.push.apply(obj, ['two']);
console.log(obj); // OUT : { '1' : 'two', index : 'one' , length : 2}
obj.push('three');
console.log(obj); // OUT : obj.push is not a function
우선 arr 객체에 push를 사용했을 땐 해당 객체는 배열 표준 메서드인 push() 를 가지고 있으므로 정상적으로 작동을 하는 것이다. 하지만 obj 객체에서 push() 메서드를 활용하기 위해서는 다소 복잡해보이는 구문으로 적용을 하여 추가를 해야한다. 이러한 방식으로 원소를 추가한 객체를 유사 배열 객체라고 부르며 완전히 배열이 되는것이 아니므로 obj.push(‘three’); 구문에서 위와 같은 오류를 출력하는 것이다.
'⚙️ Node.js' 카테고리의 다른 글
[NestJS] Async, 비동기로 인한 프로세스 중단 방지 (0) | 2024.08.21 |
---|---|
[Javascript 심화] 함수 1 (0) | 2024.01.28 |
[Javascript 심화] 객체와 참조 (2) | 2024.01.27 |
[NodeJS] Gmail SMTP로 인증메일 전송하기 (0) | 2023.11.08 |
[Node.js] path 모듈에 대해 알아보자 (0) | 2023.02.20 |