⚡유사배열이란?
유사 배열 객체(array-like object)은 length 프로퍼티를 갖는 객체로 문자열, arguments, HTMLCollection, NodeList 등은 유사 배열이다.
유사 배열 객체는 length 프로퍼티가 있으므로 순회할 수 있으며 call, apply 함수를 사용하여 배열의 메소드를 사용할 수도 있다.
https://poiemaweb.com/js-type-check
너무나도 명쾌한 설명이네요
length 프로퍼티가 있고 인덱스로 접근이 가능하지만
배열은 아닌 것
근데 문자열은 알겠는데
arguments는 뭐임?
🔍arguments
function func1(a, b, c) {
console.log(arguments[0]);
// expected output: 1
console.log(arguments[1]);
// expected output: 2
console.log(arguments[2]);
// expected output: 3
}
func1(1, 2, 3);
함수의 매개인자를 arguments라고 하는 군요..
이걸 인덱스로 접근이 가능한지 진짜 처음알았네요
🔍Immutability
Immutability(변경불가성)는 객체가 생성된 이후 그 상태를 변경할 수 없는 디자인 패턴을 의미한다.
Immutability은 함수형 프로그래밍의 핵심 원리이다.
대략 변경할 수 없는 이라는 뜻이네요
근데 이런 immutability를 가지고 있는 자료형이 뭐가 있을까용
- Boolean
- null
- undefined
- Number
- String
- Symbol (New in ECMAScript 6)
이런 원시타입값들은 변경불가성을 가지고 있고
그 외의 타입값들은 모두 Object타입이라고 합니다.
근데 나머지는 납득이 가는데 Number, string은 우리가 자주 바꾸지 않나요??
var str = 'Hello';
str = 'world';
만약 이렇게 할당을 해준다고 하면 우리는 str의 값을 수정한 게 아니라
첫번째 구문이 실행되면 메모리에 문자열 ‘Hello’가 생성되고 식별자 str은 메모리에 생성된 문자열 ‘Hello’의 메모리 주소를 가리킨다.
그리고 두번째 구문이 실행되면 이전에 생성된 문자열 ‘Hello’을 수정하는 것이 아니라 새로운 문자열 ‘world’를 메모리에 생성하고 식별자 str은 이것을 가리킨다.
이때 문자열 ‘Hello’와 ‘world’는 모두 메모리에 존재하고 있다.
변수 str은 문자열 ‘Hello’를 가리키고 있다가 문자열 ‘world’를 가리키도록 변경되었을 뿐이다.
ㄷㄷ.. 너무나도 무섭네요
그래서 우리는 string[i]로 접근은 할 수 있지만 string은 immutable하기에
read only이고 string[i]만 배열처럼 값을 변경할 수가 없는거였네요
🔍객체의 의도치않은 변경
var user1 = {
name: 'Lee',
address: {
city: 'Seoul'
}
};
var user2 = user1; // 변수 user2는 객체 타입이다.
user2.name = 'Kim';
console.log(user1.name); // Kim
console.log(user2.name); // Kim
분명 user2의 밸류를 변경한건데
왜 user1 객체까지 밸류가 변경된걸까요..?
위의 경우 객체 user2의 name 프로퍼티에 새로운 값을 할당하면 객체는 변경 불가능한 값이 아니므로 객체 user2는 변경된다.
그런데 변경하지도 않은 객체 user1도 동시에 변경된다.
이는 user1과 user2가 같은 어드레스를 참조하고 있기 때문이다.
너무 무섭네요...
var user = {
name: 'Lee',
address: {
city: 'Seoul'
}
};
var myName = user.name; // 변수 myName은 string 타입이다.
user.name = 'Kim';
console.log(myName); // Lee
myName = user.name; // 재할당
console.log(myName); // Kim
그럼 이건 왜 변경이 안되는걸까요?
변수에 밸류를 할당했으니
string타입인 밸류는 변경불가능한값이니까..
user.name의 값을 변경했지만 변수 myName의 값은 변경되지 않았다.
이는 변수 myName에 user.name을 할당했을 때 user.name의 참조를 할당하는 것이 아니라 immutable한 값 ‘Lee’가 메모리에 새로 생성되고 myName은 이것을 참조하기 때문이다.
따라서 user.name의 값이 변경된다 하더라도 변수 myName이 참조하고 있는 ‘Lee’는 변함이 없다.
정말 너무나도 무섭습니다.
결국 같은 어드레스를 참조하느냐 그렇지않느냐의 차이로
객체의 의도치않은 변경이 일어나는 거라고 볼 수 있겠네요!!
근데 이러면 우리가 객체를 변경하면 객체를 참조한 다른 객체들이 다 변경되는것을 의도하면 상관없을수 있겠지만
이런걸 원하지 않을때의 해결방법이 있을까요?
물론 있읍니다.
- 객체의 방어적 복사(defensive copy)Object.assign
- 불변객체화를 통한 객체 변경 방지Object.freeze
- immutable.js
1,2번째는 성능이슈가 있고
immutable.js를 사용하는 편이 좋다고 하네요
'javascript' 카테고리의 다른 글
자바스크립트 실행 컨텍스트 (execution context) 란? (2) (1) | 2022.12.25 |
---|---|
자바스크립트 실행컨텍스트 (execution context) 란? (1) | 2022.12.25 |
자바스크립트의 프로미스 (1) | 2022.12.20 |
널리쉬 병합 연산자 '??' (Nullish coalescing operator) Javascript (1) | 2022.12.15 |
자바스크립트 JS Map()자료구조 정리! (1) | 2022.11.15 |