배열 / 유사 배열(Array-like objects) 비교 + Prototype
✓ Prototype
- https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object_prototypes
- 자바스크립트는 객체 지향적 언어이자 프로토타입 언어
- 객체 간 관계 정의
- 모든 객체는 다른 객체를 기반으로 생성, 이때 기반으로 생성된 객체 -> 프로토타입
- 프로토타입은 객체의 기본적 구조와 메서드를 정의하는데 사용
- 모든 객체들이 메소드와 속성들을 상속 받기 위한 템플릿으로써 프로토타입 객체(prototype object)를 가짐
- 프로토타입 체이닝 : 해당 객체에 직접 정의된 메서드나 속성을 찾고, 상위 프로토타입 체인을 따라 올라가면서 찾음
- 프로토타입 체이닝을 통해 상위 객체의 메서드를 사용할 수 있음
- prototype method : arrayInstance.filter() 처럼, 내가 직접 선언한 array 인스턴스에 체이닝해서 사용, 해당 객체의 인스턴스에 대해 호출되서 사용 -> Array.prototype 에 정의
- static method : Array.isArray() 처럼, Array 객체에 직접 체이닝. Array 객체의 생성자에 정의된 메서드, 객체의 인스턴스와 독립적으로 사용 가능
✓ Array(배열)
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
- 원시값이 아니라 객체
- 자바스크립트 배열은 사이즈 조정 가능, 다양한 데이터 형식을 혼합해 저장
- 숫자(정수) 인덱스를 사용해서 접근
- length 속성으로 배열의 사이즈를 늘리고 줄일 수 있음
- Sparse arrays : 빈 슬롯(empty slots)를 포함한 배열
- 배열을 중첩하여 다차원 배열로 생성 가능
- 프로퍼티 추가 가능 ex) array.property = "hi";
- 정적 메서드 : Array.from(), Array.fromAsync(), Array.isArray(), Array.of()
- 인스턴스 메서드 : Array.prototype.map(), Array.prototype.reduce() 등 공식 문서 참고
// 다차원 배열
const a = new Array(4);
for (let i = 0; i < 4; i++) {
a[i] = new Array(4);
for (let j = 0; j < 4; j++) {
a[i][j] = `[${i}, ${j}]`;
}
}
✓ 배열 복사 연산
- 얕은 복사 : spread 연산자, Array.from(), Array.prototype.slice(), Array.prototype.concat()
-> 값을 복사 하는게 아니라, 원본 객체와 같은 참조(메모리 내 같은 값을 가리킴)를 공유하는 복사본
- 깊은 복사 : JSON.stringify() -> Json.parse(), structuredClone()
const fruits = ["Strawberry", "Mango"];
const fruitsAlias = fruits;
// 'fruits' and 'fruitsAlias' are the same object, strictly equivalent.
fruits === fruitsAlias; // true
// Any changes to the 'fruits' array change 'fruitsAlias' too.
fruits.unshift("Apple", "Banana");
console.log(fruits);
// ['Apple', 'Banana', 'Strawberry', 'Mango']
console.log(fruitsAlias);
// ['Apple', 'Banana', 'Strawberry', 'Mango']
✓ Array-like Objects(유사 배열)
- 배열처럼 숫자 인덱스 사용
- length 속성
- 배열의 메서드(push, pop, forEach, ..)를 직접 사용할 수 없음
- Array 의 인스턴스가 아님
- ex) NodeList
const arrayLike = {0: 'a', 1: 'b', 2: 'c', length: 3};
console.log(arrayLike.length); // 3
// arrayLike.push('d'); // TypeError: arrayLike.push is not a function
✓ Working with array-like objects
- Some JavaScript objects, such as the NodeList returned by document.getElementsByTagName() or the arguments object made available within the body of a function, look and behave like arrays on the surface but do not share all of their methods. The arguments object provides a length attribute but does not implement array methods like forEach().
Array methods cannot be called directly on array-like objects.
Array 처럼 행동하지만, Array의 메서드를 공유하지 않는 자바스크립트 Objects
예시) NodeList, 함수의 arguments
length 속성 제공 O, forEach 메서드 제공 X
✓ NodeList
- https://developer.mozilla.org/en-US/docs/Web/API/NodeList
- 노드 컬렉션 objects
- Node.childNodes 속성이나 document.querySelectrotAll() 메서드를 호출하면 NodeList 반환
- Node.childeNodes : NodeList(Live collection), DOM의 변경사항을 실시간으로 컬렉션에 반영
- document.querySelectorAll() : NodeList(Static collection), DOM을 변경해도 컬렉션에 영향 X
- 메서드
1) item() : 인덱스 반환
2) forEach() : NodeList의 element를 함수에 전달
3) entries(), keys(), values() : iterator 반환, 컬렉션에 포함된 모든 키/값 순회
- cf. 순서를 보장하지 않는 for .. in 문은 사용 금지, 대신 순서를 보장하는 for .. or 문 사용
var list = document.querySelectorAll("input[type=checkbox]");
Array.prototype.forEach.call(list, function (item) {
item.checked = true;
});
✓ 유사 배열 객체 -> 배열 변환
- Array.from(arrayLike, mapFn?, thisArg?) : 순회 가능 객체나 유사 배열 객체를 배열로 변환 # Array.from
- spread 연산자 사용
const arrayLike = {0: 'a', 1: 'b', 2: 'c', length: 3};
const arr = Array.from(arrayLike);
console.log(arr); // ['a', 'b', 'c']
const nodeList = document.querySelectorAll('div');
const arr = [...nodeList];
console.log(arr); // 배열로 변환된 NodeList