들어가며
본 게시글은 자바스크립트 완벽 가이드 (데이빗 플래너건) ‘3장’을 정리 & 요약하는 글입니다.
3장. 타입, 값, 변수
-
자바스크립트 타입은 기본 타입과 객체 타입 둘로 나뉨
- 자바스크립트의 기본 타입에는 숫자, 문자열, 불(boolean) 타입
- 자바스크립트의 특별한 값인 null과 undefined는 기본 값이지만 숫자나 문자열, 불에 속하지 않음
- 자바스크립트에서 숫자, 문자열, 불, 심벌, null, undefined 중 어느 것에도 속하 지 않는 값은 모두 객체
-
일반적인 자바스크립트 객체는 이름 붙은 값의 순서 없는 집합
- 그 중, 특별한 객체인 배열도 있음
- 자바스크립트에는 기본적인 객체와 배열 외에도 유용한 객체 타입이 많음
Set 객체는 값의 집합입니다. Map 객체는 키와 값의 연결입니다. 형식화 배열은 바이트 배열과 다른 이진 데이터를 연결합니다. RegExp 타입은 텍스트 패턴입니 다. 이 타입을 이용해 문자열에서 정교한 매칭, 검색, 대체 동작을 할 수 있습니다. Date 타입은 날짜와 시간을 표현하며 간단한 날짜 계산도 할 수 있습니다. Error 타입과 그 하위 타입은 자바스크립트 코드 실행 중에 일어날 수 있는 에러를 가리킵니다.
-
자바스크립트의 함수와 클래스는 그저 문법의 일부분이라고 볼 수는 없는데, 이 점이 다른 정적 언어와의 차이점
- 자바스크립트의 함수와 클래스는 그 자체가 값이므로 프로그램에서 조작할 수 있음
-
자바스크립트 인터프리터는 자동으로 가비지 컬렉션을 수행해 메모리를 관리
- 따라서 자바스크립트 프로그래머는 일반적으로 객체나 다른 값을 직접 파괴 하거나 할당을 해제할 필요는 없음
- 프로그램에서 어떤 값을 더는 참조하지 않 게 되면 인터프리터는 그 값을 다시 사용할 수 없음을 인식하고 그 값이 차지하고 있던 메모리를 자동으로 다시 확보
-
자바스크립트는 객체 지향 프로그래밍 스타일을 지원
a.sortO // sort(a)의 객체 지향 버전
- 자바스크립트의 객체 타입은 가변(mutable)이며 기본 타입은 불변(immutable)
- 자바스크립트는 값의 타입을 자유롭게 변환함
- 프로그램에서는 상수와 변수의 이름을 통해 값을 참조
3.2 숫자
- 자바스크립트의 숫자 타입인 Number는 정수와 함께 실수를 대략적으로 표현
- 자바스크립트는 IEEE 754 표준에서 정의하는 64비트 부동 소수점 형식1을 사용 해 숫자를 표현함. 이에 따라 최대 ±1.7976931348623157 x 10^308, 최소 ±5 x 10^-324 범위의 숫자를 표현할 수 있음
- 자바스크립트 프로그램에 직접 기입한 숫자를 숫자 리터럴이라 부름
3.2.1 정수 리터럴
- 자바스크립트 프로그램에서 10진 정수는 연속된 숫자로 표현함
- 또한, 자바스크립트는 10진 정수 리터 럴뿐 아니라 16진수 값도 인식함
// 아래는 모두 js의 정수 리터럴
0
3
10000000
0xff // 255: (15*16 + 15)
0xbadcafe // => 195939070
3.2.2 부동 소수점 리터럴
- 부동 소수점 리터 럴에는 소수점이 포함될 수 있음
3.14
2345.6789
0.333333333333333333
6.02e23 // 6.02 x 10^23
1.4738223e-32 // 1.4738223 x 10^-32
3.2.3 자바스크립트의 산술 연산
-
자바스크립트는 산술 연산자를 통해 숫자를 조작함
-
산술 연산자에는 덧셈의 +, 뺄셈의 곱셈의 *, 나눗셈의 /, 나머지의 %가 있음
-
ES6에서 Math 객체에 함수가 더 추가됨
-
자바스크립트는 산술 연산 과정 에 0으로 나누거나 오버플로, 언더플로가 발생해도 에러를 일으키지 않음
- 계산 결과가 자바스크립트가 표현할 수 있는 가장 큰 숫자보다 큰 경우(오버플로)에는 특별한 값 Infinity를 반환
- 마찬가지로, 음수의 절댓값이 자바스크립트가 표현할 수 있는 가장 큰 음수의 절댓값보다 크다 면 결과는 음의 무한대 인 -Infinity
- 자바스크립트에서는 0으로 나눠도 에러가 일어나지 않음. 무한대 또는 음의 무한대를 반환할 뿐입니다. 여기엔 한 가지 예외가 있는데, 0을 0으로 나누는 경우 는 정의되어 있지 않으므로 이 결과는 특별한 값 NaN(숫자가 아님)임
- NaN 값은 자기 자신을 포함해 어 떤 값과도 같지 않다는 특징
3.2.4 이진 부동 소수점 숫자와 반올림 오류
- 실수는 무한히 많지만, 자바스크립트의 부동 소수점 형식으로 정확히 표현할 수 있 는 숫자는 유한함 (정확히 18,437,736,874,454,810,627개)
- 따라서 자바 스크립트로 실수를 다룰 때 실제 숫자의 근삿값으로 표현될 때가 자주 있음
- 위 예시에서 반올림 오류 때문에 0.3과 0.2의 차이의 근삿값은 0.2와 0.1의 차이의 근삿값과 같 지 않다고 나옴
- 이 문제는 이진 부동 소수점 숫자를 사용하는 프로그래밍 언어에서 모두 발생함
3.2.5 Biglnt로 임의 정확도를 부여한 정수
- Biglnt는 ES2020에서 정의한 자바스크립트의 최신 기능 중 하나
- Biglnt는 값이 정수인 숫자 타입임. 이 타입은 다른 프로그래밍 언어나 API와의 호환에 필요한 64비트 정수를 표 현하기 위해 추가됨
- BigInt 리터럴은 연속된 숫자 다음에 소문자 n을 붙인 형식
1234n // 그렇게 크지는 않은 Biglnt 리터럴
0x8000000000000000n // => 2n**63n: 64비트 정수
- Biglnt()함수를 써서 일반적인 자바스크립트 숫자나 문자열을 Biglnt로 변환할 수 있음
Biglnt(Number.MAX_SAFE_INTEGER) // => 9007199254740991n
let string = '1' + '0'.repeat(100) // 1 뒤에 0이 100개 있습니다.
Biglnt(string) // => 10n**100n: 1구골
- Bi잉nt 값의 산술 연산은 일반적인 자바스크립트 숫자의 산술 연산과 비슷하지만, 나눗셈을 할 때 나머지를 버 린다는 점이 다름
3.2.6 날짜와 시간
- 자바스크립트의 Date 클래스는 날짜와 시간에 대응하는 숫자를 표현하고 조작
- Date는 객체이지만, 타임스탬프인 숫자 표현 역시 가지고 있으므로 1970년 1월 1일로부터 몇 밀리초가 지났는지 등을 계산할 수 있음
3.3 텍스트
- 자바스크립트에서 텍스트를 표현하는 타입은 문자열
- 문자열은 16비트 값 이 순서에 따라 이어진 형태이며, 기본 값이므로 불변
- 각 값은 일반적으로 유니코드 문자
3.3.1 문자열 리터럴
- 자바스크립트 프로그램에 문자열을 사용할 때는 그 문자열을 앞뒤가 맞는 작은따옴표(‘), 큰따옴표(“), 백틱(’) 쌍으로 묶으면 됨
"" // 빈 문자열: 문자가 들어 있지 않습니다.
'testing' "3.14"
,name=,,myfom,''
"Wouldn't you prefer O'Reilly's book?"
"t is the ratio of a circle's circumference to its radius" '"She said 'hi'", he said.
- ES6 백틱 문법 역시 문자열을 여러행으로 나누어 쓸 수 있는데,이 경우 에는 줄 끝 문자가 문자열 리터럴에 포함됨
- 또한, 클라이 언트 사이드 자바스크립트 프로그래밍 에서는 자바스크립트 코드에 HTML 문자열이 들어갈 수 있고, HTML 안에 자바스크립트 코드가 들어갈 수 있음
<button onclick="alert('Thank you')">Click Me</button>
3.3.2 문자열 리터럴 안의 이스케이프 시퀀스
- 자바스크립트 문자열에서 역슬래시()는 그 다음 문자와 조합해서 일반적인 방법으로는 문자열에 표시할 수 없는 문자를 표현
- 예를 들어 \n은 뉴라인 문자를 표현하는 이스케이프 시퀀스
- 예를 들어 \n은 뉴라인 문자를 표현하는 이스케이프 시퀀스
3.3.3 문자열 다루기
-
자바스크립트에는 문자열을 ‘병합(연결)’하는 기능이 내장되어 있음
-
- 연산자를 문자열에 쓰면 두 번째 문자열을 첫 번째 문자열 뒤에 이어 붙임
let msg = 'Hello, ' + 'world' // 문자열 "Hello, world"
-
-
자바스크립트에는 다양한 문자열 API가 있음
s.length // 문자열의 길이를 잼
s.substring(1, 4) // => Hell": 두 번째, 세 번째, 네 번째 문자
3.3.4 템플릿 리터럴
- ES6부터는 백틱으로 감싼 문자열 리터 럴을 사용할 수 있음
- 하지만 이것은 일반적인 문자열 리터럴 문법과는 다르게, 임의의 자바스크립트 표현식을 넣을 수 있는 템플릿 리터럴임
let s = 'hello world';
let name = "Bill";
let greeting = 'Hello ${ name // greeting == "Hello Bill."
3.3.5 패턴 매칭
-
자바스크립트에는 문자열 내부의 패턴을 정의하고 매칭하는 정규 표현식(RegExp) 이라는 데이터 타입이 있음
- 정규 표현식 리터럴은 슬래시 한 쌍 사이에 텍스트를 쓰는 형태
- 두 번째 슬래시 뒤에도 글자 하나 이상 쓸 수 있으며 이 글자는 패턴의 의미를 수정
;/^HTML/ // 문자열의 시작 부분에 있는 H T M L에 일치합니다. ;/[1-9] [0-9]*/ // 00| 아닌 숫자가 하나 있어야 하고 그 뒤의 숫자는 제한이 없습니다. ;/\bjavascript\b/i // javascript가 한 단어로 들어가야 하고 대소문자를 구분하지 않습니다.
3.4 불 값
- 불 값은 참 또는 거짓을 표현 (true, false)
- 불 값은 일반적으로 비교 결과를 나타낸다
a === 4 // true
- 또한, 불 값은 제어문에서 자주 사용됨
if (a === 4) {
b = b + 1
} else {
a = a + 1
}
if((x===0S&y===0) || !(z===0)){
// x와 y가 모두 0 이거나, z가 0이 아닐때
}
3.5 null과 undefined
- null은 값이 없음을 나타낼 때 사용하는 특별한 값
- null에 typeof 연산자를 사용하면 문자열 “object”를 반환하는데, 이로 미루어 null은 ‘객체가 없다’는 것을 나타내는 특별한 객체 값
- undefined 값 은 좀 다른 의미에서 값이 없음을 나타냄
- 이 값은 초기화되지 않은 변수의 값 이며 존재하지 않는 객체 프로퍼티나 배열 요소에 접근했을 때 반환되는 값
- 또한 값을 명시적으로 반환하지 않는 함수의 반환 값이며, 전달되지 않은 인자의 값
- undefined는 미리 정의된 전역 상수이며 그 값은 undefined로 초기화됨
- undefined에 typeof 연산자를 적용하면 문자열 “undefined”를 반환
3.6 심벌
- 심벌(Symbol)은 문자열이 아닌 프로퍼티 이름으로 ES6에서 추가됨
- 자바스크립트의 객체 타입이 프로퍼티의 순서 없는 집합이며 각 프로퍼티에 이름과 값이 있다
- 프로퍼티 이름은 일반적 으로 문자열
- 하지만 ES6 이후에는 심벌 역시 문자열과 같은 목적으로 사용할 수 있음
- 심벌 값을 가져올 때는 Symbol() 함수를 호출
- 이 함수는 절대 같은 값을 반환하지 않고, 같은 인자로 호출하더라도 다른 값을 반환
- 즉, Symbol() 을 호출해 심벌 값을 얻었다면 객체의 기존 프 로퍼티를 같은 이름으로 덮어 쓸 염려 없이 그 값을 프로퍼티 이름으로 추가할 수 있음
3.7 전역 객체
- 전역 객체의 프로퍼티는 전역으로 정의된 식별자이며 모든 자바스크립트 프로그램에서 사용할 수 있음
- 자바스크립트 인터프리터를 시작 할 때마다(또는 웹 브라우저가 새 페이지를 로드할 때마다) 다음과 같은 프로퍼티를 가진 새 전역 객체를 생성
- undefined. Infinity, NaN 같은 전역 상수
- isNaNO, parselnt()(3.9.2절), eval()(4.12절) 같은 전역 함수
- DateO, RegExpO, StringO, Object(), Array()(3.9.2절) 같은 생성자 함수
- Math와 JS0N(6.8절) 같은 전역 객체
- 전역 객체의 초기 프로퍼티는 예약어가 아니지만 예약어로 간주
- 노드의 전역 객체에는 이름이 global인 프로퍼티가 있으며 그 값은 전역 객체 자체
- 웹 브라우저에서는 Window 객체가 모든 자바스크립트 코드의 전역 객체
- ES2020에서 정의한 globalThis는 어떤 환경에서든 전역 객체를 참조하는 표준
3.8 불변인 기본 값과 가변인 객체 참조
-
기본 값은 불변이다. 기본 값을 ‘변경’하는 방법은 없음
- boolean, 문자열, 숫자 모두 불변임
- boolean, 문자열, 숫자 모두 불변임
-
기본 값은 또한 값으로 비교한다. 두 값이 일치하려면 값이 같아야 한다.
- 특히, 두 개의 문자열 값을 비교할 때 자바스크립트는 두 문자열의 길이 가 같고 각 인덱스마다 같은 문자가 있어야 같은 것으로 취급
-
객체는 기본 값과는 다름. 먼저, 객체는 가변이므로 값을 바꿀 수 있음.
- 객체는 값으로 비교하지 않음. 두 객체의 프로퍼티와 값이 같다고 해서 같은 객체는 아님
- 객체는 값으로 비교하지 않음. 두 객체의 프로퍼티와 값이 같다고 해서 같은 객체는 아님
-
객체를 기본 타입과 구별하기 위해 참조 타입이라 부를 때도 있음.
-
이 용어는 객체 값은 참조이며, 객체는 참조로 비교한다는 뜻
-
3.9 타입 변환
- 자바스크립트는 값의 타입을 강제하지 않음
- ex) 자바스크립트가 문자열을 예상한다면, 그 자리에 있는 값은 무엇이든 문자열로 변환됨
- ex) 자바스크립트가 문자열을 예상한다면, 그 자리에 있는 값은 무엇이든 문자열로 변환됨
3.9.1 변환과일치
- 일치 연산자
===
는 두 피연산자가 다른 타입이면 같지 않다고 판단하며, 동등 연산자==
를 선택하는 것보다 거의 항상 더 좋다. - 아래 값은 모두 true 이다
3.9.2 명시적 변환
-
자바스크립트 자동으로 타입을 변환하기는 하지만 때때로 직접 변환해야 할 때도 있다
-
명시적으로 타입을 변환하는 가장 단순한 방법은 Boolean(), Number(), String() 함수
-
묵시적인 타입 변환을 수행하는 자바스크립트 연산자를 타입 변환을 목적으로 쓸 때도 있음
-
- 연산자의 피연산자 중 하나가 문자열이면 다른 피연산자도 문 자열로 변환됨
- 연산자의 피연산자 중 하나가 문자열이면 다른 피연산자도 문 자열로 변환됨
-
3.9.3 객체를 기본 값으로 변환
-
자바스크립트가 객체를 기본 값으로 변환하는 규칙이 복잡한 이유 중 하나는 일 부 객체는 여러 가지 기본 값으로 표현될 수 있다는 점
- 예를 들어 Date 객체 는 문자열로도, 숫자인 타임스탬프로도 표현할 수 있음
-
자바스크립트 명세에 는 객체를 기본 값으로 변환하는 세 가지 기본적인 알고리즘이 정의되어 있음
- 객체를 불로 변환: 객체는 모두 true로 변환됩니다. 이 변환에 는 알고리즘이 적용되지 않으며, 문자 그대로 모든 객체에 적용됨
- 객체를 문자열로 변환: 객체를 문자열로 변환해야 할 때 자바스크립트는 먼저 문자열 선호 알고리즘을 사 용해 기본 값으로 변환한 다음, 필요하다면 표 3-2(51페이지 참고)의 규칙에 따라 그 기본 값을 문자열로 변환
-
**toString()**과 valueOf() 메서드:
- 모든 객체는 기본 값으로 변환할 때 사용하는 두 가지 변환 메서드를 상속
3.10 변수 선언과 할당
- 이름 또는 식별자를 사용해 값을 표현하는 것은 컴퓨터 프로그래밍 의 가장 기본적 인 기술
- 값에 이름을 부여하면 프로그램에서 그 값을 참조하고 사 용할 수 있음. 이런 과정을 일반적으로 변수에 값을 할당한다고 함
- 자바스크립트 프로그램에서 변수나 상수를 쓰기 전에 반드시 선언을 먼저 해야 함
3.10.1 let과 const를 사용한 선언
- 최신 자바스크립트(ES6 이후)에서는 다음과 같이 let 키워드를 사용해 변수를 선언합니다.
- let 문에서 변수에 초깃값을 할당하지 않으면 값을 할당할 때까지 undefined로 남습니다.
- 가능하면 다음과 같이 변수를 선언할 때 초깃값을 할당하는 것이 좋은 프로그래밍 습관입니다.
- 가능하면 다음과 같이 변수를 선언할 때 초깃값을 할당하는 것이 좋은 프로그래밍 습관입니다.
- 상수를 선언할 때는 const를 사용합니다. const는 let과 거의 비슷하지만, 선언 할 때 반드시 값을 할당해 초기화해야 한다는 점이 다릅니다.
- 이름에서 짐작할 수 있듯 상수의 값은 바꿀 수 없습니다. 상수의 값을 바꾸려 하면 TypeError가 일어납니다.
- let과 const로 선언한 변수와 상수는 블록 스코프를 가집니다. 이 말은 let이 나 const 문이 존재하는 블록 안에서만 해당 변수와 상수가 유효하다는 뜻
- 선언이 어떤 코드 블록에도 속하지 않고 최상위 레벨에 있을 경우 이를 전역 변수 또는 상수라고 부르며, 이들은 전역 스코프를 가집니다.
- 같은 스코프에서 같은 이름으로 let이나 const 선언을 하나 이상 사용하는 것은 문법 에러입니다.
- 자바스크립트의 변수는 어떤 타입의 값이든 가질 수 있습니다. 예를 들어 자바 스크립트에서는 변수에 숫자를 할당한 다음 다시 문자열을 할당하는 것도 가능
3.10.2 var를 사용한 변수 선언
- ES6 전의 자바스크립트에서는 변수를 선언하는 방법이 var 키워드 하나뿐이었으며 상수를 선언하는 방법은 없었습니다.
- var의 문법은 let과 똑같습니다.
- let 과의 차이점:
- var로 선언한 변수는 블록 스코프를 갖지 않습니다.
- var 로 선언된 전역 변수는 전역 객체(3.7절)의 프로퍼티로 존재합니다.
- let 선언과는 달리 var는 같은 변수를 몇번이고 선언 할 수 있습니다.
- var 선언에서 가장 생소한 특징은 호이스팅(끌어올림)이라는 기능입니다. var로 변수를 선언하면 이 선언문은 함수의 맨 위로 끌어올려집니다.
3.10.3 분해 할당
- ES6에서는 선언과 할당을 합친 일종의 복합 문법을 도입했으며 이를 분해 할당 (destructuring assignment)이라고 부릅니다.
- 분해 할당이 일어나면 오른쪽 값에서 하나 이상의 값을 추출(분해)해서 왼쪽에 있는 변수에 할당합니다.
- 분해 할 당은 const, let, var 선언문의 일부로 변수를 초기화하기 위해 사용하는 경우가 대 부분이지만 일반적인 할당 표현식에서도 사용할 수 있습니다.
참고
- 데이비드 플래너건, 『자바스크립트 완벽 가이드』, 도서출판인사이트(2022), p25-268.