
Number형 – 정수, 부동 소수점 숫자 등의 숫자를 나타낼 때 사용합니다. 정수의 한계는 ±253 입니다.BigInt형 – 길이 제약 없이 정수를 나타낼 수 있습니다.String형 – 빈 문자열이나 글자들로 이뤄진 문자열을 나타낼 때 사용합니다. 단일 문자를 나타내는 별도의 자료형은 없습니다.Boolean형 – true, false를 나타낼 때 사용합니다.Null형 – null 값만을 위한 독립 자료형입니다. null은 알 수 없는 값을 나타냅니다.Undefined형 – undefined 값만을 위한 독립 자료형입니다. undefined는 할당되지 않은 값을 나타냅니다.Symbol형 – 객체의 고유 식별자를 만들 때 사용합니다.Object형 – 복잡한 데이터 구조를 표현할 때 사용합니다.자바스크립트 형 변환 (암묵적 형 변환)
ㅇ 암묵적 형 변환
- (수치 → 문자열)
. + 연산자 : 피 연산자들을 문자열로 형변환
.. 例) 3 + "0" => 문자열 "30"
- (문자열 → 수치)
. `-`,`*` 이항 연산자 : 피 연산자들을 수치로 형변환
.. 例) var test = "3"; test - 0 => 숫자 3
. `+` 단항 연산자 : 피 연산자를 수치로 형변환
.. 例) var test = "3"; +test => 숫자 3
- (수치,문자열 → 논리형)
. `!` 단항 연산자 : 피 연산자를 Boolean으로 형변환하고, 부정(negate) 연산을 함
ㅇ 비교 연산에 따른 암묵적인 형변환 결과
- == 비교 연산자 : 우선, 형변환을 해보고, 그 다음에 비교 과정을 수행함
. 단, 기본 타입의 경우에는 저장된 값에 대해 형변환 후 비교를 수행하지만,
참조 타입의 경우에는 저장된 값이 주소이므로, 비교 수행이 별 의미없음
- === 비교 연산자 : 형변환을 수행하지 않고, 엄격한 비교 과정을 수행함
ㅇ 논리 연산에 따른 암묵적인 형변환 결과 (즉, 조건문이나, Boolean() 함수의 결과)
- false로 간주되는 값들
. 빈 문자열 (''), 0, -0, NaN, null, undefinded => false
- true로 간주되는 값들
. 0을 제외한 숫자, 빈 문자열을 제외한 문자열, 모든 객체, 심볼
자바스크립트 형 변환 (명시적 형 변환)
ㅇ 대부분, 암묵적인 자동 형 변환을 하지만, 때때로 명시적인 형 변환을 하려면,
- 주로, Boolean(),Number(),String(),Object() 함수를 많이 이용함
ㅇ 수치를 문자열로 명시적인 형변환 : Object, Number 객체의 메소드들을 이용하는 방법, 반환 값들이 문자열
- toString() - Object 타입
- toLocaleString() - Object 타입
- toFixed() - Number 타입
- toExponential() - Number 타입
- toPrecision() -Number 타입
* 例) var num = 1234.567;
. num.toString() => "1234.567" (10진법)
. num.toString(16) => "4d2.9126E978d5" (16진법)
. num.toFixed(0) => "1234" (소수점 이하 버림)
. num.toFixed(2) => "1234.57" (소수점 이하 2자리에서 반올림)
. num.toFixed(4) => "1234.5670" (소수점 이하 4자리)
. num.toExponential(3) => "1.235e+3" (소수점 이하 3자리 표기 후 지수 표현)
. num.toPrecision(6) => "1234.57" (유효숫자 6개로 표현하되, 반올림)
. num.toPrecision(3) => "1.23e+3" (유효숫자 3개로 표현하되, 정수부 작으면 지수 표현)
ㅇ 문자열을 수치형으로 명시적인 형변환
- Number() 함수 : 문자열 등 모든 데이터형을 실수(부동소수점)로 형변환
. 例) Number("3.14") => 3.14, Number(true) => 1, Number(null) => 0,
Number(undefined) => NaN, Number([1,2,3]) => Nan, Number(NaN) => NaN
- parseInt() : 문자열을 정수로 형변환
. 例) parseInt("3.14") => 3
- parseInt(num,base) : base로 지정된 진법으로 해석하여 10진수 정수 형변환
. 例) parseInt("101",2) => 이진수로 해석하여 10진수 5
- parseFloat() : 소수점,지수 표현까지 포함한 문자열을 실수(부동소수점)로 형변환
. 例) parseFloat("3.14") => 3.14
- `-`,`*` 연산자
ㅇ 논리형으로 명시적인 형변환
- Boolean 함수: 숫자 0, 빈 문자열, null, undefined, NaN과 같이 직관적으로도 “비어있다고” 느껴지는 값들은 false가 됩니다. 그 외의 값은 true로 변환됩니다.
불변 객체 사용하는 이유
필요에 의해
객체에 변화를 가해도 원래의 객체가 그대로 남아있어야 하는 경우이다.
예측가능성
프론트에서는 모든 app에서 많은 상태를 선언하고, 이후 run을 하게 되면 업데이된 상태가 초기 상태와 크게 달라져, 상태를 변경하면 변경 사항이 숨겨지고 여러 버그를 유발할 수 있는 부작용이 생성되어 디버깅이 어려워진다. 하지만 immutable 객체를 사용하여 단순하게 유지하면 주어진 시간에 데이터를 예측하는 것이 더 쉬워진다.
성능
변경할 수 없는 개체를 만드려면 메모리 비용이 드는 것은 사실이다. 불변 객체에 값을 추가할 때 새 객체를 생성해야하면 이 새객체에서 기존 값을 새 값을 복사하여 추가메모리가 필요하다. 그리고 이 메모리 소비를 줄이기 위해 구조적 공유를 사용하게 되는데, 결국 새로운 값을 값을 반환하지만 소수의 개체만 내부적으로 할당 되기 때문에 효율적이디.
변경사항 추적
불변성의 장점 중 하나는 reference 및 value의 동일성을 여부를 사용하여 애플리케이션을 최적화할 수 있다. 이렇게 하면 변경된 사항이 있는지 쉽게 식별한디. 예를 들어 shouldComponentUpdate는 상태 객체를 비교하여 상태가 동일한지 확인하고 불필요한 렌더링을 방지한다. immutable을 사용하면 일련의 이벤트처럼 이러한 객체에 발생하는 변경 사항을 추적 가능하다.
불변 객체 만들기
immutable 라이브러리 활용
공식 사이트 : https://immutable-js.com/
const { Map } = require('immutable');
const map1 = Map({ a: 1, b: 2, c: 3 });
const map2 = Map({ a: 1, b: 2, c: 3 });
// map1과 map2는 동일한 property를 가졌으나, 참조값이 다름
console.log(map1.equals(map2)); // true
console.log(map1 === map2); // false
console.log("-----------------------------")
// map1을 이용하여, 같은 값을 가진 새로운 map3를 만들었을 때, 같은 참조값을 가짐
const map3 = map1.set('b', 2); // Set to same value
console.log(map1.equals(map3)); // true
console.log(map1 === map3); // true
console.log("-----------------------------")
// map1, 2를 복사하여, map3, map4를 만들면 같은 참조값을 가짐
const map4 = map1;
console.log(map4 === map1); //true
map1.set('a',2)
map4.set('a',3);
console.log(map1.get('a')); // 1
console.log(map4.get('a')); // 1
console.log(map4 === map1)
const map5 = map2;
console.log(map5 === map2); //true
console.log(map4.equals(map5)) // true
console.log("-----------------------------")
// map1을 이용하여, 다른 값을 가진 새로운 map6를 만들었을 때, 다른 참조값을 가짐 (새로 생성)
const map6 = map1.set('b', 5); // Set to diffrent value
console.log(map6.get('b')); // 5
console.log(map1.equals(map6)); //false
console.log(map1 === map6); //false
map6.set('b',2) // Set to same value
console.log(map6.get('b')); // 5
console.log(map1.equals(map6)); //false
console.log(map1 === map6); //false
const와 Object.freeze()를 이용
function deepFreeze(object) {
// Retrieve the property names defined on object
const propNames = Object.getOwnPropertyNames(object);
// Freeze properties before freezing self
for (const name of propNames) {
const value = object[name];
if (value && typeof value === "object") {
deepFreeze(value);
}
}
return Object.freeze(object);
}
const obj2 = {
internal: {
a: null
}
};
deepFreeze(obj2);
obj2.internal.a = 'anotherValue'; // fails silently in non-strict mode
obj2.internal.a; // null```
단순 객체 깊은 복사
Object.assign()
중첩 객체 깊은 복사
표준 알고리즘을 이용한 객체 복사
https://html.spec.whatwg.org/multipage/structured-data.html#structuredserializeinternal
loadash의 매서드인 _.cloneDeep(obj)을 사용한 복사
공식 주소: https://lodash.com/docs/4.17.15#cloneDeep
JSON.parse(JSON.stringify())을 이용한 복사
ref. http://www.ktword.co.kr/index.php, https://ko.javascript.info/, https://developer.mozilla.org/ko/docs/Web/JavaScript/, https://dassur.ma/things/deep-copy/, https://noogoonaa.tistory.com/91, https://poiemaweb.com/js-immutability, https://www.geeksforgeeks.org/why-is-immutability-so-important-in-javascript/