Posts You don't know JS Yet - 2장 자바스크립트 조망하기
Post
Cancel

You don't know JS Yet - 2장 자바스크립트 조망하기

2.1 파일은 프로그램입니다

웹사이트 하나, 애플리케이션 하나를 프로그램 하나로 생각하기 쉽지만, JS에서는 파일 각각이 별도의 프로그램이다. 이러한 관점은 오류 처리와 관련이 깊은데, JS는 파일을 프로그램으로 취급하기에 파일 하나에만 오류가 있어도 다음 파일이 처리되지 않을 수 있다.

독립적인 js 파일을 하나의 프로그램으로 작동시키는 방법은 전역 스코프를 사용해 파일간 상태를 공유하고 공통으로 사용하는 기능을 접근할 수 있도록 만드는 방법뿐이다. 이렇게 전역스코프에서 여러 .js 파일이 조합되면 이 파일들은 런타임에서 하나의 애플리케이션으로서 작동한다

하지만 어떤 구성을 사용하든 js 파일 하나는 고유한 작은 프로그램이라고 생각해야한다.

2.2 값

  • JS에 값은 원시타입과 객체타입으로 구분된다. 원시타입과 객체타입은 변수에 할당하거나 넘길때 동작 차이가 있다. (값 vs 참조)
  • null, undefined를 구분없이 사용하는 경향이 있지만, 비어있는 값을 나타날때는 undefined를 사용하는 것이 가장 안전하다
  • 원시타입으로는 심볼도 존재한다. 심볼은 사람이 추측할 수 없게 만든 특수한 숨김 값이며, 객체에서 특정한 키를 만들때 주로 사용한다. 하지만 보통 개발자가 직접 사용하는 일은 적고, 라이브러리 등 저차원 코드에서 주로 사용한다.
    • ex) hitchhikerGuide[Symbol("삶의 의미")]

배열

  • 배열은 특수한 유형의 객체이며, 객체 내 정렬된 데이터에는 숫자 인덱스가 매겨진다.
  • 배열에는 원시타입, 객체타입 상관없이 모든 타입의 값이 들어갈 수 있다. 함수도 값이기에 들어간다.

객체

  • 배열보다 일반적인 데이터 타입으로, 정렬되지 않은 키-값 쌍을 모아놓은 컬렉션이다

값의 타입

  • typeof 키워드를 사용해 원시타입값과 객체 타입값을 구분한다
  • typeof null은 “object”를 반환하며, typeof function(){} 은 “function”을 반환한다.

2.3 변수 선언과 사용

JS에서 값은 리터럴 값으로 표현하거나 변수에 담긴채로 다뤄진다.

변수를 사용하려면 먼저 변수 선언(생성)이 선행되어야한다.

  • var, let : var는 함수 스코프, let은 블록 스코프
  • const : 블록스코프, 선언하는 순간에 값 할당해야하며 값 재할당 불가능
    • 다만 재할당이 안되지, 변경은 가능하다. 따라서 객체를 할당하면 그 객체 내 값들은 변경할 수 있어진다.

2.4 함수

JS 에서 함수는 프로시저를 프로그램에 녹여낼 수 있도록 해야한다

  • 프로시저 : 한번 이상 호출할 수 있고, 입력값이 있을 수 있으며 하나 이상의 출력값을 반환하는 구문의 모음

JS에서는 함수를 다음과 같이 만들 수 있다

  • 함수 선언문 : function someFunction(paramter) {...} 와 같은 형태로 생성
    • 함수와 식별자(someFunction)와의 관계는 컴파일 단계에서 맺어진다.
  • 함수 표현식 : var someFunction = function() {...}
    • 함수 식별자와 함수가 코드를 실행하기 전까지 관계가 맺어지지 않음

JS에서 함수는 할당 가능하고, 어디든 전달 가능한 값이다. 이는 함수형 프로그래밍을 지원하는 언어에서는 필수적인 스펙이다. 함수는 값이므로 객체의 프로퍼티로 사용할 수도 있다.

2.5 비교

JS에서 같음을 비교할때는 “정확하게” 일치하는냐와 “아주 유사”, “교환 가능”을 비교할때도 있다. 따라서 일치 비교동등 비교의 차이를 알고 있어야한다.

===(일치연산자)은 대부분의 상황에서는 값과 타입을 함께 비교하여 예상 가능하게 동작한다. 하지만 다음 두 경우에서는 예상과 다르게 작용한다.

  • NaN === NaN = false : 대신 Number.isNaN() 사용
  • 0 === -0 = true : 대신 Object.is() 사용

또한 원시 타입이 아닌 객체끼리 비교할때는 참조를 비교하기에 예상과 다르게 동작할 수 있다.

  • [1,2,3] === [1,2,3] = false 참조는 독자성을 가지기에 객체 구조가 같은지 비교하는 방법은 직접 코드를 짜는 방법밖에 없다. 하지만 이경우에도 함수를 가진 객체끼리 비교할때, 함수끼리 비교할때는 난이도가 복잡해진다. (또한 클로저 등은 고려할 수 없음)

강제변환

==(동등연산자)는 피연산자가 다른 타입일경우 비교 이전에 타입을 강제변환한 후 ===와 동일하게 비교한다.(흔히들 오해하는 타입을 고려하지 않는 ===과는 다른 방식임) 이때 타입 강제 변환은 >=, <=, <,> 등에서도 일어난다.

비교연산자의 강제 변환은 다음과 같이 이루어진다.

  • 피연산자가 모두 문자열인 경우 : 알파벳순으로 문자열 비교
  • 그 외 : 숫자 타입으로 변환해 비교 진행

강제 조건부 비교 : if,삼항연산자, while, for 등의 조건절에서 일어나는 비교

  • if(x) => if(Boolean(x) === true)로 변환해서 비교됨. 따라서 x = "asdasd" 인 상황에서는 해당 조건절이 실행된다.

2.6 코드 구조화 패턴

JS 생태계에서 코드 구조화 패턴은 크게 클래스와 모듈이 있다.

클래스

  • 클래스는 데이터와 해당 데이터를 조작하는 동작이 포함된다.
  • 클래스는 구체적인 값이 아니며, 사용하려면 new 키워드를 통해 인스턴스를 만들어야한다.
  • 상속과 다형성을 통해 데이터를 체계적으로 구성할 수 있다

모듈

클래식 모듈

  • 최소한 한 번 이상 실행되는 외부 함수로, 모듈 인스턴스 내부의 숨겨진 데이터를 대상으로 작동하는 함수가 있는 인스턴스를 반환 한다.
  • 모듈 팩토리라고 설명하기도 한다
1
2
3
4
5
6
7
8
9
function Publication(title, author, pubDate) {
	var publicAPI = {
		print() {
			console.log(`제목 : ${title}, 저자 : ${auhor}, 발행일 : ${pubDate}`);
		}
	}

	return publicAPI;
}
  • 클래스에서는 내부 데이터에 접근하려면 this를 사용해야하지만, 모듈에서는 스코프내 식별자 역할을 하는 변수를 사용해 메서드와 데이터에 접근할 수 있다.
  • (자바스크립트의) 클래스는 인스턴스의 메서드, 데이터가 모두 외부에 공개되지만, 모듈에서는 원하는 것만 객체에 담아 반환할 수 있다
  • 현재도 AMD, UMD, CommonJS 를 사용해 작성한 JS 프로그램에서 흔하게 발견되지만 호환성이 떨어져 자주 사용되진 않는다.

ES 모듈

  • ES6 에서 도입된 모듈 시스템
  • 클래식 모듈과의 차이점
    • ES 모듈에는 모듈을 정의하는 래핑 함수가 없다. 파일이라는 맥락에서 구현된다. (ES 모듈 파일 하나가 모듈 하나)
    • ES 모듈을 사용할 때 모듈 API와 직접 상호작용하지 않는다. export 를 통해 원하는 메서드, 변수만 외부에 공개할 수 있다
    • 인스턴스화하지 않아도 import 키워드를 통해 가져오면 단일 인스턴스처럼 사용할 수 있다
      • 한번 import 해서 가져오면 인스턴스가 생기고, 다른 곳에서 다시 import 하면 만들어진 인스턴스의 참조만 가져온다. -> 사실상 싱글턴
      • 여러개의 인스턴스를 만들고 싶다면 클래식 모듈이나 클래스를 export하면 됨. (클래식 모듈이 좀 더 권장됨)
This post is licensed under CC BY 4.0 by the author.

You don't know JS Yet - 1장 자바스크립트

You don't know JS Yet - 3장 자바스크립트 뿌리 파헤치기

Comments powered by Disqus.