계획했던대로 자격증 취득도 다 해서, 8월부터는 알고리즘과 팀프로젝트에 전념할 계획이였다.
하지만 알고리즘 스터디를 하기전에 JS 기본기를 탄탄하게 다져두고 하는게 깊은 이해에 도움이 될 것 같았다.
때마침 회사 프런트 엔드 직원분들이 "모던 자바스크립트 Deep Dive" 와 "코어 자바스크립트" 두 책을 강추해주셨다.
그동안 나는 인강이 좀 더 잘 맞는다고 생각했어서, 우선 끝까지 읽기에 상대적으로 얇은 책으로 선택했다.
처음엔 가볍게 "혼동되는 개념만 잡고 빨리 알고리즘으로 넘어가야지. " 라는 생각뿐이였는데
1, 2 단원을 읽고 생각이 바뀌었다.
남들이 이해한 내용을 듣기만 하는게 아닌, 책을 보면서 곰곰히 고민하고 이해하는것도 잘 정리가 되었다.
그래서 단원별로 포스팅하면서 한번 더 머리속에 정리를 해보려고한다.
01. 데이터 타입
데이터 타입과 변수 선언
var a; // 변수 a 선언
a = 'abc'; // 변수 a에 데이터 할당
var a = 'abc'; // 변수 선언과 할당을 한 문장으로 표현
이런 식으로 변수 선언과 데이터 할당에 대해서는 알고 있었지만 깊게 들어가 보자.
데이터할당에 대한 메모리 변화를 표로 살펴보자.
1. 변수 영역에서 빈 공간(@1003)을 우선 확보
2. 확보한 공간의 식별자를 a로 지정
3. 데이터 영역의 빈 공간(@5004)에 문자열 'abc'를 저장
4. 앞서 저장한 문자열의 주소(@5004)를 @1003의 공간에 대입
그리고 만약
// var a = 'abc'
var a = 'abcdef'
이런식으로 데이터 영역에 새로운 값을 할당하면
1. 데이터 영역에 빈 공간(@5005)에 문자열 'abcdef'를 저장
2. 앞서 저장한 문자열의 주소(@5005)를 @1003의 공간에 다시 대입
이렇게 기존 문자열에 새 값이 할당되더라도 무조건 새로 만들어 별도의 공간에 저장한다.
변수와 상수를 구분 짓는 변경 가능성의 대상은 위 사진의 변수 영역 메모리이다.
변수: 한 번 할당된 데이터 영역에 재할당이 가능.
상수: 재할당이 불가능.
반면 불변성 여부를 구분 할 떄의 변경 가능성의 대상은 데이터 영역 메모리이다.
var a = 10;
var b = a;
b = 15;
/////////////////
var obj1 = { c:10, d:’ddd’ };
var obj2 = obj1;
obj2.c = 20;
해당 두 코드의 결과값 비교부터 해보자면
a !== b
obj1 === obj2
이 결과가 바로 기본형과 참조형 데이터의 가장 큰 차이점이다.
사진으로 보면 이해가 바로 될 것이다.
첫번째 case를 먼저 보면
b에 15라는 값이 할당 되는순간, 변수 영역 주소 1002에 있던 b는
데이터 영역에서 빈 주소(@5004)를 찾아서 15를 저장하고,
저장한 문자열의 주소(@5004)를 @1002의 공간에 다시 대입한다.
따라서 기본형 데이터를 복사했던 a와 b 는 이제 다른 주소를 바라보고 서로 다른 값이 된 것이다.
두번째 case를 보면
obj2의 프로퍼티를 변경해도 변수 @1003과 @1004가 바라보는 데이터 주소는 변함이 없다.
하지만 데이터 영역에 아직 20이 없으므로 새로운 공간 @5005에 저장하고,
@5002가 가리키는 변수 영역에서 다시 c를 찾아(@7103) 그곳에 @5005를 대입한다.
따라서 참조형 데이터를 복사 했던 obj1과 obj2는 여전히 같은 객체를 바라보고 있는 상태이다.
기본형 데이터: 실제 값이 저장되는 형태로, 값이 변경되면 새로운 메모리 공간에 저장.
참조형 데이터: 주소를 통해 값을 참조하는 형태로, 내부 프로퍼티가 변경되어도 참조 주소는 그대로.
var obj1 = { c:10, d:'ddd' };
var obj2 = obj1;
obj2 = { c: 15, d:'123' };
하지만 이 세번째 case를 보자.
이때 결과 다음과 같다.
obj1 !== obj2
지금은 왜 같지 않을까?
내부의 프로퍼티를 변경한게 아니라 데이터 자체를 변경한거라서
obj2 의 변수 영역의 바라보는 주소자체가 바뀌게 된다.
따라서 obj1 과 obj2는 이제 서로 다른 주소를 바라보는 다른 값이 되어버린 것이다.
참조형 데이터가 '가변값'이라고 설명할 때의 '가변'은 참조형 데이터자체를 변경할 경우가 아니라
그 내부의 프로퍼티를 변경할 때만 성립된다. ⭐️
기본형과 참조형의 차이점과 메모리 상에서 어떻게 동작하는지 이해하면, 더욱 효과적인 코드를 작성할 수 있을 것 같다!
불변객체 이해하기
불변 객체는 한 번 생성되면 그 상태를 변경할 수 없는 객체다.
자바스크립트와 같은 언어에서는 객체에 대한 변경을 막기 위해 불변 객체를 사용하는 경우가 종종 있다.
그럼 어떻게 이게 작동하는지 살펴보자.
1. 얕은 복사(Shallow Copy)
: 객체의 첫 번째 레벨만 복사해. 나머지는 참조로 연결되므로 원본 객체에 영향을 줄 수 있다.
2. 깊은 복사(Deep Copy)
: 내부의 모든 값을 하나하나 찾아 전부 복사해서 독립된 원본을 만들어. 원본 객체에 영향을 주지 않는다.
기본형은 그대로 복사하고, 참조형은 내부의 프로퍼티들을 재귀적으로 복사해야 깊은 복사가 이루어진다.
이 깊은 복사의 예제코드를 보자.
var copyObjectDeep = function(target){
var result = {};
if(typeof target === 'object' && target !== null ){
for(var prop in target){
result[prop] = copyObjectDeep(target[prop]);
}
} else {
result = target;
}
return result;
}
좀 더 간단하게 깊은 복사를 처리 할 수 있는 JSON을 활용한 깊은 복사 코드를 보자.
var copyObjectViaJSON = function(target) {
return JSON.parse(JSON.stringify(target));
}
// JSON.parse(...): 앞서 JSON 형식의 문자열로 변환된 target 객체를 다시 일반 자바스크립트 객체로 파싱한다.
// 그 결과로 완전히 새로운 객체가 생성된다.
객체를 Json문법으로 표현된 문자열로 전환했다가 다시JSON객체로 바꾸는 방법이다.
하지만 이 방법은 메서드나 숨겨진 프로퍼티, getter/setter 등과 같이 JSON으로 변경할 수 없는 프로퍼티는 무시된다.
그래서 순수한 정보만 다룰 때 활용하기 좋다.
null과 undefined의 차이점
1. null
타입: typeof null의 결과는 "object". 이건 JavaScript의 초기 버전에서 발생한 버그로, 지금까지 수정되지 않았다.
의미: 명시적으로 값이 없음을 나타내고 싶을 때 사용한다.
2. undefined
타입: typeof undefined의 결과는 "undefined".
의미: 변수가 선언되었지만 값이 할당되지 않았을 때 자동으로 할당되는 값.
null과 undefined는 == (동등 비교)를 사용할 경우 서로 동등하다고 간주된다.
이건 null과 undefined만의 특별한 케이스다.
=== (일치 비교)를 사용하면 null은 null과만 일치하고, undefined는 undefined와만 일치하게 된다.
var n = null;
console.log(typeof n); // "object"
console.log(n == undefined) // true
console.log(n === undefined) // false
console.log(n == null) // true
console.log(n === null) // true
null과 undefined는 비슷한 개념이지만, 다르게 취급되는 경우가 있어서,
가능한 일치 비교(===)를 사용하는 습관을 들이는 것이 좋을 것 같다.
'Programming Language > Javascript' 카테고리의 다른 글
[Javascript] new Set() 배열에서 쉽게 중복값 제거하기 (0) | 2023.08.14 |
---|---|
[Javascript] 실행 컨텍스트_코어 자바스크립트 (0) | 2023.08.13 |
[Javascript] null 병합연산자 "??" (0) | 2023.04.11 |
[Javascript] split() 지정 구분기호로 문자열을 배열로 분할 (0) | 2023.03.30 |
[Javascript] "some()" 배열의 객체에 원하는 값이 있으면 True 반환 (0) | 2023.03.25 |