2023.03.08.
TIL / JavaScript
70p
데이터 타입
자바스크립트의 모든 값은 데이터 타입을 갖는다. 데이터 타입이 필요한 이유는 다음과 같다.
72p
동적 타입 언어와 정적 타입 언어
정적 타입 언어는 변수 선언 시점에 변수의 타입이 결정되고 변수의 타입을 변경할 수 없다. 자바스크립트에서는 값을 할당하는 시점에 변수의 타입이 동적으로 결정되고 변수의 타입을 언제든지 자유롭게 변경할 수 있다.
다시말해, 자바스크립트의 변수는 선언이 아닌 할당에 의해 타입이 결정(타입 추론)된다. 그리고 재할당에 의해 변수의 타입은 언제든지 동적으로 변할 수 있다.
이러한 특징을 동적 타이핑이라 하며, 자바스크립트를 정적 타입 언어와 구별하기 위해 동적 타입 언어라 한다.
87p
드 모르간의 법칙
논리 연산자로 구성된 복잡한 표현식은 가독성이 좋지 않아 한눈에 이해하기 어려울 때가 있다. 이러한 경우 드 모르간의 법칙을 활용하면 복잡한 표현식을 좀 더 가독성 좋은 표현식으로 변환할 수 있다.
!(x || y) === (!x && !y)
!(x && y) === (!x || !y)
123p
null 병합 연산자
var foo = '' || 'default string'
var foo2 = '' ?? 'default string'
console.log(foo) // 'default string'
console.log(foo) // ""
null 병합 연산자 ??는 변수에 기본값을 설정할 때 유용하다. null 병합 연산자가 도입되기 이전에는 논리 연산자 ||를 사용한 단축 평가를 통해 변수에 기본값을 설정했다.
논리연산자를 사용한 단축 평가의 경우 좌항의 피연산자가 false로 평가되는 값이면 우항의 피연산자를 반환한다. 만약 0이나 ‘’도 기본값으로서 유효하다면 예기치 않은 동작이 발생할 수 있다.
하지만 null 병합 연산자는 좌항의 연산자가 false로 평가되는 값 이라도 null또는 undefined가 아니면 좌항의 피연산자를 그대로 반환한다.
137p
원시타입과 객체타입
자바스크립트가 제공하는 7가지 데이터 타입(숫자, 문자열, 불리언, null, undefined, 심벌, 객체타입)은 크게 원시타입과 객체타입으로 구분할 수 있다.
원시타입과 객체타입은 크게 세 가지 측면에서 다르다.
138p
원시값
원시 타입의 값, 즉 원시 값은 변경 불가능한 값이다. 다시말해, 한번 생성된 원시 값은 읽기 전용 값으로서 변경할 수 없다.
이 때, 변경이 불가능하다는 말은 원시 값 자체를 변경할 수 없다는 것이지 변수 값을 변경할 수 없다는 것이 아니다.
변수는 하나의 값을 저장하기 위해 확보된 메모리 공간 자체 또는 그 메모리 공간을 식별하기 위해 붙인 이름이고, 값은 변수에 저장된 데이터로서 표현식이 평가되어 생성된 결과를 말한다. 변경 불가능하다는것은 변수가 아니라 값에 대한 진술이다.
변수 값을 변경하기 위해 원시 값을 재할당하면 새로운 메모리 공간을 확보하고 재할당한 값을 저장한 후, 변수가 참조하던 메모리 공간의 주소를 변경한다. 값의 이러한 특성을 불변성이라 한다.
불변성을 갖는 원시 값을 할당한 변수는 재할당 이외에 변수 값을 변경할 수 있는 방법이 없다.
163p
일급객체
자바스크립트의 함수는 일급 객체다.
함수가 일급 객체라는것은 함수를 객체와 동일하게 사용할 수 있다는 의미다. 객체느 값이므로 함수는 값과 동일하게 취급할 수 있다. 따라서 함수는 값을 사용할 수 있는곳(변수 할당문, 객체의 프로퍼티 값, 배열의 요소, 함수 호출의 인수, 함수 반환문)이라면 어디서든지 리터럴로 정의할수 있으며 런타임에 한수 객체로 평가된다.
일급 객체로서 함수가 가지는 가장 큰 특징은 일반 객체와 같이 함수의 매개변수에 전달할 수 있으며, 함수의 반환값으로 사용할 수도 있다는 것이다. 이는 함수형 프로그래밍을 가능케 하는 자바스크립트의 장점중 하나다.
165p
함수 호이스팅
console.dir(add) // f add(x, y)
console.dir(sub) // undefined
function add(x, y) {
return x + y
}
var sub = function (x, y) {
return x - y
}
위 예제와 같이 함수 선언문으로 정의한 함수는 함수 선언문 이전에 호출할 수 있다. 그러나 함수 표현식으로 정의한 함수는 함수 표현식 이전에 호출할 수 없다. 이는 함수 선언문으로 정의한 함수와 함수 표현식으로 정의한 함수의 생성 시점이 다르기 때문이다.
모든 선언문이 그렇듯 함수 선언문도 코드가 한 줄씩 순차적으로 실행되는 시점인 런타임 이전에 자바스크립트 엔진에 의해 먼저 실행된다. 다시말해, 함수 선언문으로 함수를 정의하면 런타임 이전에 함수 객체가 먼저 생성된다. 그리고 자바스크립트 엔진은 함수 이름과 동일한 이름의 식별자를 암묵적으로 생성하고 생성된 함수 객체를 할당한다.
즉, 코드가 한 줄씩 순차적으로 실행되기 시작하는 런타임에는 이미 함수 객체가 생성되어 있고 함수 이름과 동일한 식별자에 할당까지 완료된 상태다. 따라서 함수 선언문 이전에 함수를 참조할 수 있으며 호출할 수도 있다. 이처럼 함수 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 자바스크립트 고유의 특징을 함수 호이스팅 이라 한다.
177p
순수함수, 함수형 프로그래밍
외부 상태를 변경하지 않고 외부 상태에 의존하지도 않는 함수를 순수 함수라 한다. 순수 함수를 통해 부수효과를 최대한 억제하여 오류를 피하고 프로그램 안전성을 높이려는 프로그래밍 패러다임을 함수형 프로그래밍이라 한다.
199p
자바스크립트는 렉시컬 스코프를 따르므로 함수가 어디서 호출했는지가 아니라 함수를 어디서 정의했는지에 따라 상위 스코프를 결정한다. 함수가 호출된 위치는 상위 스코프 결정에 어떠한 영향도 주지 않는다.
이처럼 함수의 상위 스코프는 함수 정의가 실행될 때 정적으로 결정된다. 함수 정의(함수 선언문 또는 함수 표현식)가 실행되어 생성된 함수 객체는 이렇게 결정된 상위 스코프를 기억한다. 함수가 호출될 때마다 함수의 상위 스코프를 참조할 필요가 있기 때문이다.
206p
모듈패턴
클래스를 모방해서 관련이 있는 변수와 함수를 모아 즉시 실행 함수로 감싸 하나의 모듈을 만든다. 모듈패턴은 자바스크립트의 강력한 기능인 클로저를 기반으로 동작한다. 모듈 패턴의 특징은 전역 변수의 억제는 물론 캡슐화까지 구현할 수 있다는 것이다.
캡슐화
캡슐화는 객체의 상태를 나타내는 프로퍼티와 프로퍼티를 참조하고 조작할 수 있는 동작인 메서드를 하나로 묶는 것을 말한다. 캡슐화는 객체의 특정 프로퍼티나 메서드를 감출 목적으로 사용하기도 하는데 이를 정보 은닉이라 한다.
213p
일시적 사각지대(Temporal dead zone)
‘let’키워드로 선언한 변수는 스코프의 시작 지점부터 초기화 단계 시작 지점(변수 선언문)까지 변수를 참조할 수 없다. 스코프의 시작 지점부터 초기화 시작 지점까지 변수를 참조할 수 없는 구간을 일시적 사각지대(TDZ)라고 부른다.
239p
바인딩
바인딩이란 식별자와 값을 연결하는 과정을 의미한다. 예를들어, 변수 선언은 변수 이름(식별자)과 확보된 메모리 공간의 주소를 바인딩하는 것이다. this바인딩은 this(키워드로 분류되지만 식별자 역할을 한다)와 this가 가리킬 객체를 바인딩하는 것이다.