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)
      • 문자열 가능
      • 문자열 내부에 표현식 가능
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에서 새롭게 도입된 비교 문법 (객체 비교에는 적합하지 않음.)

+ Recent posts