이번장은 중요한지 내용이 길다.
1)배열
배열은 자바스크립트 객체의 특별한 형태이다.
크기를 지정하지 않아도 되고 어떠한 위치에 어느 타입의 데이터를 저장하더라도 에러가 발생하지 않는다.
1-1)배열 리터럴
앞에서 객체 리터럴을 경험해봐서 비슷하다. 다른점은 대괄호( [ ] )를 사용한다.
1 2 3 4 5 6 | //배열 리터럴을 통한 5개 원소를 가진 배열 생성 var colorArr = ['orange', 'yellow, 'blue', 'green', 'red']; console.log(colorArr[0]); //orange console.log(colorArr[1]); //yellow console.log(colorArr[4]); //red | cs |
객체 리터럴에서는 프로퍼티 이름과 프러퍼티 값을 모두 표기해야 했지만, 배열 리터럴에서는 각 요소의 값만을 포함한다.
객체가 프로퍼티의 이름으로 대괄호나 마침표 표기법을 이용해 해당 프로퍼티에 접근했다면, 배열의 경우는 대괄호 내에 접근하고자 하는 원소의 배열 내 위치 인덱스값을 넣으면 접근이 가능하다.
1-2)배열의 요소 생성
객체가 동적 프로퍼티를 추가하듯 배열도 동적으로 배열 원소를 추가할 수 있다.
값을 순차적으로 넣을 필요 없이 아무 인덱스 위치에나 값을 동적으로 추가할 수 있다.
1 2 3 4 5 6 7 8 9 10 11 | //빈 배열 var emptyArr = []; console.log(emptyArr[0]); //undefined // 배열 요소 동적 생성 emptyArr[0] = 100; emptyArr[3] = 'eight'; emptyArr[7] = true; console.log(emptyArr); // [100, 3: "eight", 7: true]; console.log(emptyArr.length); // 8 | cs |
배열 요소에 값을 동적으로 추가했다.
배열 0, 3, 7 번째에 값을 추가했는데 출력해보면 0, 3, 7번째에 해당한 값이 들어간걸 볼 수 있다.
나머지 1,2,4,5,6은 undefind값이 추가된다.
length를 찍어보면 8이라는 숫자를 볼 수 있는데 이건 배열의 가장 큰 값을 를 기준으로 보여준다.
1-3)배열의 length 프로퍼티
length 프로퍼티는 배열의 원소 개수를 나타내지만, 실제로 배열에 존재하는 원소 개수와 일치하는 것은 아니다.
배열 내의 가장 큰 인덱스에 1을 더한 값을 보여준다. 그 때문에 배열의 가장 큰 인덱스값이 변하면 length 또한 바뀐다.
1 2 3 4 5 6 7 8 | var arr = []; console.log(arr.length); // 0 arr[0] = 0; arr[1] = 1; arr[2] = 2; arr[100] = 100; console.log(arr.length); // 101 | cs |
배열 원소에 값을 저장할수록 가장 큰 인덱스값의 length 값이 늘어나는 것을 확인 할 수 있다.
하지만 실제 메모리는 length 크기처럼 할당되지 않는다.
1 2 3 4 5 6 7 8 9 | var arr = [0, 1, 2]; console.log(arr.length); // 3 arr.length = 5; console.log(arr); // [0, 1, 2, undefined x 2] arr.length = 2; console.log(arr); // [0, 1] console.log(arr[2]) // undefined | cs |
배열에 처음 3개를 할당하고 length를 5로 바꿔보았다 값을 출력해보면 실제로는 [0, 1, 2]만 출력되지만 책에는 undefined까지 넣어준걸로 봐선 뭔가 의미하겠지라고 생각이 든다.
그 다음 length를 2로 다시 할당하고 밑에 결과를 보면 arr[2]가 undefined로 변해있는걸 볼 수 있다.
이것은 위에서 length값을 2로 변경해서 인덱스값 2가 삭제된 것이다.
1-4)배열 표준 메서드와 length프로퍼티
배열은 사용 가능한 다양한 표준 메서드를 제공한다.
length 프로퍼티를 기반으로 동작한다. (push(), concat(), unshift(), splice(), shift(), pop(), sort(), reverse() 등...) 맛보기로 push() 메서드만 살펴보자.
1 2 3 4 5 6 7 8 9 10 | 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", "three", 5: "four"] | cs |
push() 메서드는 쉽게 말해서 가장 끝자리에 값을 추가해주는 기능이다.
length를 변경한 후에 push()를 추가해주니 4번째 인덱스가 출력이 안되고 5번째로 바로 'four'값이 입력된걸 볼 수 있다.
4번째 인덱스는 undefined의 값이 추가 된것이다.
1-5)배열과 객체
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | //colorsArr 배열 var colorsArr = [ 'orange', 'yellow', 'green' ]; console.log(colorsArr[0]); //orange console.log(colorsArr[1]); //yellow console.log(colorsArr[2]); //green //colorsObj 객체 var colorsObj = { '0' : 'ornge', '1' : 'yellow', '2' : 'green' } console.log(colorsObj[0]); //orange console.log(colorsObj[1]); //yellow console.log(colorsObj[2]); //green //typeof 연산자 비교 (1) console.log (typeof colorsArr); // Object (not array) console.log (typeof colorsObj); // Object //length 프러퍼티 (2) console.log(colorsArr.length) //3 console.log(colorsObj.length) //undefined //배열 표준 메서드 (3) colorsArr.push('red'); //[ 'orange', 'yellow', 'green', 'red' ] colorsObj.push('red'); //Uncaught TypeError: colorsObj.push is not a function(…) | cs |
처음 배열과 객체에 서로 비슷하게 요소를 넣어주었다.
(1)typeof 연산자를 찍어보니 둘다 Object가 출력된다. 이건 배열도 객체로 인식하고 있다는 것이다.
(2)length 연산자를 찍어보니 배열은 3이라는 값을 출력하고 객체 리터럴 방식은 undefined 값이 출력된다. 이건 객체에 length 프러퍼티가 존재하지 않는다는걸 확인 할 수 있다.
(3)배열 표준 메서드의 push()를 사용해 보았는데 배열은 red가 추가되었고 객체에는 에러가 발생 되었다.
이건 프로토타입 관계도를 봐야된다.
객체 -> Object.prototype
배열 -> Array.prototype -> Object.prototype
객체같은경우에 바로 Object.prototype의 상속을 받는다.
하지만 배열은 Array.prototype가 추가 되어있다.
1-6)배열과 프로퍼티 동적 생성
배열도 객체이므로 배열 원소 이외에도 객체처럼 동적으로 프로퍼티를 추가할 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | //배열 생성 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); Array[4] 0: "zero" 1: "one" 2: "two" 3: "red" color: "blue" length: 4 name: "number_array" __proto__: Array[0] | cs |
프러퍼티를 추가했지만 length값은 바뀌지 않았다.
배열에 원소를 추가해보고 다시 length값을 확인했더니 4가 찍힌다.
그럼 color와name은 어디로간걸까
dir()로 확인해보니 자세히 확인할 수 있다.
즉 프러퍼티가 추가는 되지만 length값은 배열에 원소가 추가되야만 증가하는걸 알 수 있다.
1-7)배열의 프로퍼티 열거
객체는 for in 문으로 프로퍼티를 열거한다. 배열도 객체이기 때문에 for in문을 사용해서 모든 프로퍼티를 열거할 수 있다.
하지만 불필요한 프러퍼티가 출력되므로 for문을 사용하는게 좋다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | for(var prop in arr) { console.log(prop, arr[prop]); } // 결과값 0 zero 1 one 2 two 3 red color blue name number_array for (var i = 0; i<arr.length; i++){ console.log(i, arr[i]); } //결과값 0 "zero" 1 "one" 2 "two" 3 "red" | cs |
delete와 splice등 사용법과 기능이 나와있지만 여기서는 넘어가자.