logo

형변환과 덕 타이핑

Chapter 4

42 조회

0 추천

1,162 단어

6분 예상

2024. 08. 15. 게시

2025. 02. 26. 수정

luasenvy 작성

CC BY-NC-SA 4.0

작성하면서

4번째 챕터를 보면서 각각이 자바스크립트 내에서 어떻게 동작하는지에 대해서만 보려하였으나 실제로는 암시적, 명시적에 대한 부분만 내장함수 실행을 통해 눈으로 확인할 수 있었고, 나머지는 명목,구조화,덕 타이핑은 실제로 자바스크립트에서 동작하는 것인지도 불명확하기 때문에 개념만 정리하였다.

암묵적 / 명시적 형변환

형변환은 자바스크립트를 사용하다보면 비일비재하게 마주치게 된다.

const str = String(100); // 명시적 캐스팅
const str2 = 1024 + ""; // 암묵적 캐스팅
const tf = !"" // 암묵적 캐스팅

Number(null); // 0
Number(undefined); // NaN

위 예제처럼 Number, Boolean, String 같은 내장함수를 명시적으로 호출하여 형변환을 하는 방법이 있는가 하면, 문자열이나 부울을 연산하여 암묵적으로 형변환을 할 수도 있다.

자바스크립트에서 형변환을 할 때 복잡한 경우를 많이 마주치게 된다. 예제처럼 Number를 통해 캐스팅을 할 때에도 두 반환 값이 다르다. 상식적으로는 두 값이 모두 비어있음을 나타내기 때문에 둘다 같은 값이 나오지 않을까 싶지만 말이다.

자료형의 상호작용

const a = true + false;
const b = 10 / "2";
const c = "number" + 10 + 1;
const d = [0] > null;
const e = "true" == true;
const f = {} + [] + [1];

동작해선 안될 것 같은 멍청한 코드들도 자바스크립트라면 오류없이 출력이 된다. 이런 특성은 보기에 쉽고 초기 학습장벽이 아주 낮다는 큰 장점이 있다. 초등학생 앉혀놓고 10분이면 변수에 값 넣고 간단한 사칙연산, 그리고 브라우저에 alert()까지는 가능하지 않을까?

그러나, 디버그를 어렵게 하고 직접 실행되기 전까지 작동을 예상하기 어렵게 한다는 큰 단점 또한 존재한다. 이러한 단점은 프로젝트가 커질수록 더욱 힘들게 한다. 타입 스크립트가 인기있는 이유의 1등 공신이기도 하다. "타입"이라는 이름에서부터 그 분노가 느껴진다.

이런 웃기지만 잘 작동하는 예제는 wtfjs에서 확인할 수 있다.

if ( numVariable === 0 ) console.log("exact number 0");
if ( strVariable == 0 ) console.log("number 0 or string 0 or boolean ...");

이런 느슨한 상호작용 덕분인지 비교 연산자의 경우 ===, !== 이런 생소한 연산자를 볼 수 있는데 자료형까지 비교할 때 사용한다. 이야기 하자면 너무도 많기에 더 많은 예제와 작동방식을 확인해보고 싶다면 여기에서 확인하기를 추천한다.

덕 타이핑

오리처럼 생기고, 오리처럼 헤엄치고, 오리처럼 꽥꽥거리면 아마 오리겠지

다른 말로 풀자면 "뭐, 이 정도면 그렇다 칩시다" 라고 할 수 있겠다. 어원은 DuckTest에서 찾아볼 수 있다. 타이핑이란 우리가 키보드를 타이핑할 때 사용하는 타이핑이 아니고 자료형타입을 결정하는 방식을 말한다.

필요한 멤버가 모두 있다면 호환되는 자료형임이라고 가정하는 방식이다. 두 클래스를 각각 사람과 오리라고 정의하더라도 발이 두개고 꽥꽥 소리를 낼 수 있으면 그냥 호환된다고 가정하는 것이다.

선언적 타이핑

int a = 10;

말 그대로 자료형을 선언하는 것이다. 다른 언어에서 흔히 볼 수 있다.

구조적 타이핑

class Duck {
  constructor() {
    this.sound = "quack";
  }

  makeSound() {
    return this.sound;
  }

  run() {
    return "foot";
  }
}

class Human extends Duck {
  constructor() {
    super();
    this.sound = "hello, world!";
  }
  
  think() {
    return "brain";
  }
}

const human = new Human();
console.log(human.makeSound()); // hello, world!

구조적 타이핑은 멤버를 확인하여 서로 호환되는 타입인지 확인할 수 있다. extends 예약어를 사용하여 두 클래스가 호환됨을 명시한다. Human 클래스는 Duck클래스의 모든 멤버를 가지게 되며 상속한다 라고 표현하거나 각각 부모, 자식 클래스라고 부르기도 한다.