원시 타입(primitive type)
typeof
로 확인하면 object가 리턴된다.BigInt
함수를 사용한다.Symbol()
로 생성한다.객체 타입(reference type)
7가지 원시 타입 이외의 모든 것
특징
===
로 정확히 비교할 수 없는 특이한 케이스를 비교할 수 있다. (예: -0 === +0
은 true, object.is
는 false 반환)Object.is
를 사용한다.Object.is
를 사용해 한 번 비교한 뒤, 순회를 통해 1 depth까지 비교한다.function shallowEqual(objA: mixed, objB: mixed){
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)
if(keysA.length !== keysB.length){
return 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
}
function add (a,b){
return a + b;
}
함수 표현식
Function 생성자
화살표 함수
즉시 실행 함수(IIFE)
고차 함수
함수의 부수효과를 최대한 억제한다.(순수함수)
useEffect
의 작동을 최소화하여 컴포넌트 안정성을 높인다.가능한 한 함수를 작게 만든다.
누구나 이해할 수 있는 이름을 붙인다.
특정한 형태의 객체를 반복적으로 만들기 위해 사용한다.
데이터나 이를 조작하는 코드를 추상화할 수 있다.
constructor
프로퍼티
getter
setter
인스턴스 메서드
정적 메서드
클래스의 이름으로 호출할 수 있는 메서드
정적 메서드 내부의 this가 클래스 자신을 가리키기 때문
전역 유틸 함수를 정적 메서드로 많이 활용한다.
class Car(){
static hello(){
console.log('hi');
}
}
const myCar = new Car();
myCar.hello() // 에러
Car.hello() // hi
function outerFunction(){
var x = 'hello';
function innerFunction(){
console.log(x);
}
return innerFunction;
}
const innerFunction = outerFunction(); // 1) outerFunction은 innerFunction을 반환하며 종료
innerFunction() // 'hello' - 2) x가 선언된 어휘적 환경에는 x 변수 존재 -> innerFunction()은 같은 환경에서 선언되었기 때문에 x라는 변수가 존재하는 환경을 기억한다.
function Component(){
const [state, setState] = useState()
// useState 호출이 끝나도 setState는 state의 최신값을 알고 있다.
function handleClick(){
setState((prev) => prev + 1)
}
}
const a = 1;
const b = 2;
const obj = {
a,
b,
}
// {a: 1, b: 2}
// 불가능
function doSomething(callback: unknown){
callback()
}
// 가능
function doSomething(callback: unknown){
if(typeof callback === 'function'){
callback();
return;
}
throw new Error('Callback은 함수여야 합니다.')
}
타입 가드
property in object
로 사용한다. 어떤 객체에 키가 존재하는 지 확인한다.제네릭
함수나 클래스 내부에서 단일 타입이 아닌 다양한 타입에 대응할 수 있도록 도와주는 도구
리액트의 useState 타입을 결정할 때 사용된다.
하나 이상 사용할 수 있다.
function multipleGeneric<First, Last>(a1: First, a2: Last) : [First, Last]{
return [a1, a2]
}
const [a, b] = multipleGeneric<string, boolean>('true', true);
a // string
b // boolean
인덱스 시그니처
객체의 키를 정의하는 방식. 키에 원하는 타입을 부여할 수 있다.
키의 범위를 최대한 줄이고, 존재하지 않은 키로 접근하면 undefined를 리턴하기 때문에 키를 동적으로 선언되는 경우를 최대한 지양해야 한다.
객체의 키를 좁히는 방법
// 1) record 사용
type Hello = Record<'hello' | 'hi', string>
const hello : Hello = {
hello: 'hello',
hi: 'hi'
}
// 2) 타입을 사용한 인덱스 시그니처
type Hello = {[key in 'Hello' | 'hi'] : string}
const hello : Hello = {
hello: 'hello',
hi: 'hi'
}
Object.keys() 를 사용할 때는 에러가 날 수 있음