1.1.1 자바스크립트의 데이터 타입
원시 타입(primitive type) - 객체가 아닌 모든 타입
Undefined
- 변수가 선언되었지만 값이 할당되지 않은 경우
- 선언됐지만 할당되지 않은 값
- 객체의 존재하지 않는 프로퍼티에 접근할 때
let foo // 선언되었지만 값이 할당되지 않음.
typeof foo === 'undefined'
function bar(hello) {
return hello
}
typeof bar() === 'undefined' // hello 매개변수가 전달되지 않음
null
- 아직 값이 없거나 비어있는 값
- 명시적으로 비어있음을 나타내는 값
- 존재하지 않음.
let someVar = null; // 명시적으로 아무것도 없음을 나타냄.
typeof someVar === 'Object' // JS의 버그.
// 이전 코드에서 작동할 수 없는 호환성이 깨지는 변경사항이어서 받아들여지지 않음.
Boolean
- True / False만을 가질 수 있는 데이터 타입
- 주로 조건문에서 많이 사용
- Truthy / Falsy (조건문 안에서 True / False로 취급되는 값)
- Falsy : false, 0, -0, NaN, '', null, undefined
- Truthy : true, 1, [], {} (객체와 배열은 내부에 값이 존재하는지 여부와 상관없이 truthy)
Number
- 정수, 실수를 모두 포함
- 안전 범위 : -(253 - 1) ~ 253 - 1
String
- 텍스트 타입의 데이터를 저장
- 표현방법 : 작은 따옴표('), 큰 따옴표("), 백틱(`)
- 백틱(`) : 템플릿 리터럴(template literal)
- 문자열 가능
- 문자열 내부에 표현식 가능
- 백틱(`) : 템플릿 리터럴(template literal)
const longText = `
안녕하세요!
` // 줄바꿈 가능. ', " 은 불가능
Symbol
- ES6에서 도입된 새로운 원시 타입
- 중복되지 않는 어떤 고유한 값을 나타내기 위함
const key1 = Symbol('key')
const key2= Symbol('key')
key1 === key2 // False > 같은 인수를 넘겨주더라도 동일 값으로 인정 X
// 동일 값을 사용하기 위해서는 Symbole.for 활용
Symbol.for('hello') === Symbole.for('hello') // true
Bigint
- ES2020에서 도입된 새로운 원시 타입
- Number 타입의 안전 범위를 벗어나는 큰 정수를 표현할 때 사용
객체/참조 타입(object/reference type) - 원시타입 이외의 모든 것. (배열, 함수, 정규식, 클래스)
object
const hello1 = () => {
}
const hello2 = () => {
}
hello1 === hello2 // False > 내용은 같아보여도 참조가 다르다.
1.1.2 값을 저장하는 방식의 차이
원시 타입
- 불변 형태의 값으로 저장
- 변수에 원시 타입의 값을 할당할 때, 해당 값은 메모리 영역에 직접 저장
let hello = 'hello World'
let hi = hello // hello World라는 '값'이 전달
console.log(hello === hi) // true
객체
- 변경 가능한 형태로 저장
- 객체를 다른 변수에 할당할 때, 값이 아닌 참조가 전달
- 즉, 객체의 실제 내용이 아닌 객체를 가리키는 참조가 전달
let hello = {
greet: 'hello World!'
}
let hi = {
greet: 'hello World!'
}
console.log(hello === hi) // false > 서로 다른 참조를 바라보고 있음.
console.log(hello.greet === hi.greet) // true > 원시 값인 내부 속성값은 동일
let hello = {
greet: 'hello World!'
}
let hi = hello
console.log(hello === hi) // true > 동일한 객체를 바라보고 있음.
- 변수에 저장된 것은 실제 객체가 아닌 객체의 메모리 주소이다.
- 따라서 객체를 복사할 때 참조가 복사되어, 원본 객체와 복사본 객체가 동일한 객체를 가리키게 되는 것
1.1.3 자바스크립트의 또 다른 비교 공식, Object.is
ES6에 도입된 메서드로, 두 값의 동등성을 판단
- == (느슨한 비교) : 자동 형 변환 수행
- === (엄격한 비교) : 자동 형 변환 없이 비교
- Object.is() : === 와 유사하지만, 몇가지 차이점 존재.
- +0 === -0 > true이지만, Object.is(+0, -0) > false
- NaN === NaN > false이지만, Object.is(NaN, NaN) > true
- 부동 소수점, 특수 값 비교에 유용하지만, 객체 비교에는 적합하지 않다.
- === 가 가지는 한계를 극복하기 위해 만들어 졌지만,
여전히 객체 간 비교에 있어서는 JS의 특징으로 인해 === 와 동일하게 동작하기 때문.
- === 가 가지는 한계를 극복하기 위해 만들어 졌지만,
1.1.4 리액트에서의 동등 비교
얕은 비교 수행
- 리액트는 props에서 꺼내온 값을 기준으로 렌더링을 수행하기 때문에 얕은 비교로 충분
- 객체 간 얕은 비교 : 객체의 첫 번째 깊이에 존재하는 값만 비교하는 것
- 1 depth 까지 비교 가능
import is from './objectIs';
import hasOwnProperty from './hasOwnProperty';
function shallowEqual(objA: mixed, objB: mixed): boolean {
// is() 함수로 두 객체가 정확히 동일한지 확인.
if (is(objA, objB)) {
return true;
}
// 두 인자가 모두 객체 타입인지 확인
if (
typeof objA !== 'object' ||
objA === null ||
typeof objB !== 'object' ||
objB === null
) {
return false;
}
// 두 객체의 키 개수가 동일한지 확인
// 각 키의 배열을 꺼냄
const keysA = Object.keys(objA);
const keysB = Object.keys(objB);
// 배열의 길이가 다르다면 false
if (keysA.length !== keysB.length) {
return false;
}
//두 객체의 각 키에 대해 값 비교, 하나라도 다르면 false
for (let i = 0; i < keysA.length; i++) {
const currentKey = keysA[i];
if (
!hasOwnProperty.call(objB, currentKey) ||
!is(objA[currentKey], objB[currentKey])
) {
return false;
}
}
return true;
}
export default shallowEqual;
- hasOwnProperty() 메서드는 객체가 특정 프로퍼티를 가지고 있는지 확인하는 데 사용
1.1.5 정리
데이터 타입
원시 타입 (불변형태의 값 저장, 메모리영역 차지)
1. Undefined
2. null
3. Boolean
4. Number
5. String
6. Symbol
7. Bigint
객체(참조) 타입 (변경가능한 형태로 저장, 참조를 전달)
1. Object
Object.is() : ES6에서 새롭게 도입된 비교 문법 (객체 간 비교에는 적합하지 않음.)
'Web > 모던 리액트 Deep Dive' 카테고리의 다른 글
[모던 리액트 Deep Dive] 리액트에서 자주 사용하는 자바스크립트 문법 (0) | 2024.04.29 |
---|---|
[모던 리액트 Deep Dive] 이벤트 루프와 비동기 통신의 이해 (0) | 2024.04.28 |
[모던 리액트 Deep Dive] 클로저 (0) | 2024.04.28 |
[모던 리액트 Deep Dive] 클래스 (1) | 2024.04.28 |
[모던 리액트 Deep Dive] 함수 (0) | 2024.04.27 |