-
[모던자바스크립트 Deep Dive] 4~6장개발일기/자바스크립트 2024. 8. 3. 23:05
4장 - 변수
4.1 변수란 무엇인가? 왜 필요한가?
📌 변수란 하나의 값을 저장하기 위해 확보한 메모리 공간 자체 또는 그 메모리 공간을 식별하기 위해 붙인 이름을 말한다.
📌 변수는 프로그래밍 언어에서 값을 저장하고 참조하는 메커니즘으로, 값의 위치를 가리키는 상징적인 이름
// result(변수명, 변수이름) const result = 10 + 20;
- 변수에 저장된 값(위 예제에서는 30)을 변수 값이라고 한다.
- 변수에 값을 저장하는 것을 할당(대입, 저장)이라 하고, 변수에 저장된 값을 읽어 들이는 것을 참조라 한다.4.2 식별자
📌 변수 이름을 식별자(identifier)라고도 한다. 식별자는 어떤 값을 구별해서 식별할 수 있는 고유한 이름을 말한다.
📌 식별자는 값이 아니라 메모리 주소를 기억하고 있다. 변수 이름 뿐만아니라 변수, 함수, 클래스 등의 이름은 모두 식별자다.
result(식별자) -> 0x0669F913(메모리 주소) -> 30(메모리 값)4.3 변수 선언
📌 변수 선언이란 변수를 생성하는 것을 말한다. 더 자세하게 말하면 값을 저장하기 위한 메모리 공간을 확보하고 변수 이름과 확보된 메모리 공간의 주소를 연결해서 값을 저장할 수 있게 준비하는 것
// 변수 선언(변수 선언문) const dayo; // undefined
- 변수를 사용하려면 반드시 선언이 필요하며, 변수뿐만 아니라 모든 식별자(함수, 클래스)가 선언이 필요하다.4.4 변수 선언의 실행 시점과 변수 호이스팅
📌 자바스크립트 엔진은 소스코드를 한 줄씩 순차적으로 실행하기에 앞서 모든 선언문을 소스코드에서 찾아내 가장 먼저 실행한다.
console.log(dayo); // '깔깔' const dayo = '깔깔';
자바스크립트 코드는 인터프리터에 의해 한 줄씩 순차적으로 실행되므로 console.log(dayo);가 실행되는 시점에서 참조에러가 발생할 것 처럼 보인다. 하지만 참조 에러가 발생하지 않고 dayo의 값인 '깔깔'이 출력 된다.
그 이유는 변수 선언이 소스코드가 한 줄씩 순차적으로 실행되는 시점, 즉 런타임이 아니라 그 이전 단계에서 먼저 실행되기 때문이다.
📌 이처럼 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 자바스크립트 고유의 특징을 호이스팅이라 한다.
var, let, const, function, class 키워드를 사용해서 선언하는 모든 식별자는 호이스팅 된다.4.5 값의 할당
let dayo; // 변수 선언 dayo = '요다'; // 값의 할당 let dayo = '요다'; // 변수 선언과 값의 할당
📌 여기서 주의할 점은 변수 선언과 할당의 실행 시점이 다르다는 것이다.
변수 선언은 소스코드가 순차적으로 실행되는 시점인 런타임 이전에 먼저 실행되지만 값의 할당은 소스코드가 순차적으로 실행되는 시점인 런타임에 실행된다.
1. 변수 선언 후 값의 할당console.log(dayo); // undefined let dayo; // 변수 선언 dayo = '요다' // 값의 할당 console.log(dayo); // 요다
2. 변수 선언과 값의 할당을 동시 진행console.log(dayo); // undefined let dayo = '요다'; // 변수 선언과 값의 할당 console.log(dayo); // 요다
1,2의 결과를 보다시피 호이스팅에 의해 변수 선언이 먼저 실행되고(런타임 이전) 값의 할당은 이후 순차적으로 실행(런타임 이후) 된다.4.6 값의 재할당
📌 재할당이란 이미 값이 할당되어 있는 변수에 새로운 값을 또다시 할당하는 것을 말한다.
let dayo = '요다'; // 변수 선언과 값의 할당 dayo = '다요'; // 값의 재할당
- 재할당을 하게 되면 처음 값을 할당했던 메모리 공간의 값(요다)을 지우고 새로운 값(다요)을 저장하는 것이 아니라, 새로운 메모리 공간을 확보하고 그 메모리 공간에 새로운 값(다요)을 저장한다.
- 이전 값인 요다는 어떤 식별자와도 연결되어 있지 않기 때문에 필요하지 않은 불필요한 값이 되고, 가비지 콜렉터에 의해 메모리에서 자동 해제된다.4.7 식별자 네이밍 규칙
📌 식별자(identifier)는 어떤 값을 구별해서 식별해낼 수 있는 고유한 이름을 말한다.
- 식별자는 특수문자를 제외한 문자, 숫자, 언더스코어(_), 달러 기호($)를 포함할 수 있다.
- 단, 식별자는 특수문자를 제외한 문자, 언더스코어(_), 달러 기호($)로 시작해야 한다. 숫자로 시작하는 것은 허용하지 않는다.
- 예약어는 식별자로 사용할 수 없다. (ex. await, default, class, const, let, for, if .. 등)네이밍 컨벤션(naming convention)
// 카멜 케이스(camelCase) const firstName; // 스네이크 케이스(snake_case) const first_Name; // 파스칼 케이스(PascalCase) const FirstName;
5장 - 표현식과 문
5.1 값
📌 값(value)은 식(표현식)이 평가되어 생성된 결과를 말한다.
// 10 + 20은 평가되어 숫자 값 30을 생성한다. const sum = 10 + 20; // 위 예제의 sum 변수에 할당되는 것은 10 + 20이 아니라 평가된 결과인 숫자 값 30이다.
5.2 리터럴
📌 리터럴(literal)은 사람이 이해할 수 있는 문자 또는 약속된 기호를 사용해 값을 생성하는 표기법을 말한다.
5.3 표현식
📌 표현식은 값으로 평가될 수 있는 문이다. 즉, 표현식이 평가되면 새로운 값을 생성하거나 기존 값을 참조한다.
// 리터럴 표현식 10 'Hello' // 식별자 표현식(선언이 이미 존재한다고 가정) sum person.name arr[1] // 연산자 표현식 10 + 20 sum = 10 sum !== 10 // 함수/메서드 호출 표현식(선언이 이미 존재한다고 가정) square() person.getName()
5.4 문
📌 문(statement)은 프로그램을 구성하는 기본 단위이자 최소 실행 단위다. 문의 집합으로 이뤄진 것이 바로 프로그램이며, 문을 작성하고 순서에 맞게 나열하는 것이 프로그래밍이다.
## 문법적으로 더 이상 나눌 수 없는 코드의 기본 요소를 토큰이라 한다 ex) 키워드, 식별자, 연산자, 리터럴, 세미콜론 등
// 변수 선언문 let x; // 할당문 x = 5; // 함수 선언문 function foo () {} // 조건문 if (x > 1) {console.log(x); } // 반복문 for (var i = 0; i < 2; i++) { console.log(i); }
5.5 세미콜론과 세미콜론 자동 삽입 기능
세미콜론(;)은 문의 종료를 나타낸다. 즉, 자바스크립트 엔진은 세미콜론으로 문이 종료한 위치를 파악하고 순차적으로 하나씩 문을 실행한다.
하지만, 자바스크립트에서 세미콜론은 옵션이다. 자바스크립트 엔진이 소스코드를 해석할 때 문의 끝이라고 예측되는 지점에 세미콜론을 자동으로 붙여주는 세미콜론 자동 삽입 기능(ASI)이 암묵적으로 수행되기 때문
## ESLint의 기본설정, ECMAScript 기술 위원회 에서도 세미콜론 사용을 권장하는 분위기이다.5.6 표현식인 문과 표현식이 아닌 문
📌 표현식인 문은 값으로 평가될 수 있는 문이며, 표현식이 아닌 문은 값으로 평가될 수 없는 문을 말한다.
- 표현식인 문은 값으로 평가되므로 변수에 할당할 수 있으며, 표현식이 아닌 문은 변수에 할당하면 에러가 발생한다.
// 변수 선언문은 값으로 평가될 수 없으므로 표현식이 아니다. let x; // 1, 2, 1 + 2, x = 1 + 2는 모두 표현식이다. x = 1 + 2; // 표현식이 아닌 문 let foo = let x; // SyntaxError // 표현식 let foo = 1 + 2;
6장 - 데이터 타입
📌 데이터 타입은 값의 종류를 말한다. 자바스크립트의 모든 값은 데이터 타입을 갖으며 원시타입과 객체타입으로 분류할 수 있다.
구분 데이터 타입 설명 원시타입 number 타입 숫자, 정수와 실수 구분 없이 하나의 숫자 타입만 존재 string 타입 문자열 boolean 타입 논리적 참(ture)과 거짓(false) undefined 타입 var, let, const 키워드로 선언된 변수에 암묵적으로 할당되는 값 null 타입 값이 없다는 것을 의도적으로 명시할 때 사용하는 값 symbol 타입 ES6에서 추가된 7번째 타입 객체 타입 객체, 함수, 배열 등 6.1 숫자 타입
C나 자바의 경우, 정수와 실수를 구분해서 int, long float, double 등과 같은 다양한 숫자 타입을 제공한다.
하지만 자바스크립트는 하나의 숫자 타입만 존재한다.
자바스크립트는 모든 수를 실수로 처리하며, 정수로 표시된다 해도 사실은 실수라는 것을 의미한다.
// 숫자 타입은 모두 실수로 처리된다. console.log(1 === 1.0); // true // 숫자 타입으 세 가지 특별한 값 console.log(10 / 0); // Infinity console.log(10 / -0); // -Infinity console.log(1 * 'dayo'); // NaN(not-a-number)
6.2 문자열 타입
// 문자열 타입 let string; string = '문자열'; // 작은따옴표(가장 일반적으로 사용) string = "문자열"; // 큰따옴표 string = `문자열`; // 백틱(ES6)
6.3 템플릿 리터럴📌 ES6에 도입된 문자열 표기법으로 백틱(``)을 사용해 표현한다. 멀티라인 문자열, 표현식 삽입, 태그드 템플릿 등 편리한 문자열 처리 제공
// 변수 선언 const name = 'Dayo'; const age = 30; // 템플릿 리터럴을 사용한 문자열 생성 const message = `Hello, my name is ${name} and I am ${age} years old.`; // 문자열 연결을 사용한 문자열 생성 const message = 'Hello, my name is ' + name + ' and I am ' + age + ' years old.'; // 결과 출력 console.log(message); // Hello, my name is Dayo and I am 30 years old.
6.4 불리언 타입불리언 타입의 값은 논리적 참, 거짓을 나타내는 true와 flase뿐이다.
let foo = true; console.log(foo); // true foo = false; console.log(foo); // false
6.5 undefined 타입📌 var, let 키워드로 선언하고 할당하지 않은 변수는 암묵적으로 undefined로 초기화 된다. 따라서 변수를 선언한 이후 값을 할당하지 않는다면 undefined가 반환된다.
따라서 변수를 참조했을 때, undefined가 반환된다면 선언 이후 값이 할당된 적이 없는 변수라는 것을 알 수 있다.
var dayo; console.log(dayo); // undefined let yoda; console.log(yoda); // undefined
변수에 값이 없다는 것을 명시하고 싶을 때 개발자가 직접 변수에 undefined를 할당하는 것은 본래 취지와 어긋날뿐더러 혼란을 줄 수 있으므로 권장하지 않는다.
❓ 변수에 값이 없다는 것을 명시하고 싶을 때는 어떻게 하면 좋을까?
-> 그런 경우에는 undefined를 할당하는 것이 아니라 null을 할당한다.
6.6 null 타입📌 프로그래밍 언어에서 null은 변수에 값이 없다는 것을 의도적으로 명시할 때 사용한다.
따라서 변수에 null을 할당하는 것은 변수가 이전에 참조하던 값을 더 이상 참조하지 않겠다는 의미다.
let data = 'Some data'; console.log(data); // Some data data = null; // 데이터 제거 console.log(data); // null
❓ undefined와 null의 비교
✅ undefined
의미: 변수가 선언되었지만 값이 할당되지 않은 상태를 나타냅니다.
자동 할당: 변수가 선언되었지만 초기화되지 않으면 자동으로 undefined가 할당됩니다.
기본 반환 값: 함수가 명시적으로 값을 반환하지 않으면 undefined를 반환합니다.
속성 미존재: 객체에 존재하지 않는 속성을 접근할 때 undefined를 반환합니다.
✅ null
의미: 의도적으로 값이 없음을 나타냅니다.
명시적 할당: 개발자가 의도적으로 변수에 값이 없음을 나타내기 위해 null을 할당합니다.
객체 초기화: 객체가 아직 값을 가지지 않았음을 나타낼 때 사용됩니다.
6.7 심벌 타입📌 심벌은 ES6에서 추가된 7번째 타입으로, 변경 불가능한 원시 타입의 값이다.
📌 심벌 값은 다른 값과 중복되지 않는 유일무이한 값이다. 따라서 주로 이름이 충돌할 위험이 없는 객체의 유일한 프로퍼티 키를 만들기 위해 사용한다.
// 심벌 값 생성 let key = Symbol('key') console.log(typeof key); // symbol // 객체 생성 let obj = {}; // 이름이 충돌할 위험이 없는 유일무이한 값인 심벌을 프로퍼티 키로 사용. obj[key] = 'value'; console.log(obj[key]); // value
6.8 객체 타입자바스크립트는 객체 기반의 언어이며, 자바스크립트를 이루고 있는 거의 모든 것이 객체이다. 위에 나온 원시 타입 이외의 값은 모두 객체 타입이다.
11장에서 자세히 다뤄보도록 한다.
6.9 데이터 타입의 필요성❓ 데이터 타입은 왜 필요한 것일까?
-> 값은 메모리에 저장하고 참조할 수 있어야 한다. 메모리에 값을 저장하려면 먼저 확보해야 할 메모리 공간의 크기를 결정해야 한다. 자바스크립트 엔진은 값의 종류에 따라 정해진 크기의 메모리 공간을 확보하기 때문에 필요하다.
❓ 컴퓨터는 값을 참조할 때 데이터 타입마다 다른 메모리 공간을 어떻게 알 수 있는걸까?
-> 변수에 지정된 데이터타입을 기준으로 읽어들이는 셀의 크기를 파악한다. 예를들어 숫자 타입은 8바이트 단위로 저장되므로score의 변수를 참조하면 8바이트단위로 메모리 공간에 저장된 값을 읽어들인다.let score = 100;
6.10 동적타입언어, 정적타입언어✅ 동적 타입 언어 (Dynamically Typed Language)
동적 타입 언어에서는 변수의 데이터 타입이 런타임 시에 결정됩니다. 변수에 값을 할당할 때 그 타입이 결정되며, 변수에 다른 타입의 값을 할당할 수 있습니다.
- 타입 선언: 변수 선언 시 타입을 지정할 필요가 없습니다.
- 런타임 타입 체크: 변수에 값을 할당할 때와 연산을 수행할 때 타입을 검사합니다.
- 유연성: 같은 변수에 다양한 타입의 값을 할당할 수 있습니다.
- 오류 가능성: 타입 오류가 런타임에 발생할 수 있습니다.
- JavaScript, Python, PHP, Ruby 등
✅ 정적 타입 언어 (Statically Typed Language)
정적 타입 언어에서는 변수의 데이터 타입이 컴파일 시에 결정됩니다. 즉, 변수를 선언할 때 그 변수의 타입을 명시적으로 지정해야 하며, 해당 변수에는 그 타입에 맞는 값만 할당할 수 있습니다.
- 타입 선언: 변수 선언 시 명시적으로 타입을 지정해야 합니다.
- 컴파일 시 타입 체크: 컴파일러가 코드를 컴파일할 때 타입을 검사하여 타입 오류를 발견합니다.
- 안정성: 타입 오류를 컴파일 단계에서 발견할 수 있기 때문에 런타임 오류가 줄어듭니다.
- 성능 최적화: 컴파일러가 타입 정보를 알고 있으므로, 최적화된 기계어 코드를 생성할 수 있습니다.
- C, C++, Java, Kotlin, Go, Rust, Scala 등'개발일기 > 자바스크립트' 카테고리의 다른 글
[모던자바스크립트 Deep Dive] 13~15장 (1) 2024.08.18 [모던자바스크립트 DeepDive] 10~12장 (0) 2024.08.11 [모던자바스크립트 Deep Dive] 7~9장 (0) 2024.08.04 [모던자바스크립트 Deep Dive] 1~3장 (0) 2024.08.03 [모던자바스크립트 Deep Dive] 서론 (0) 2024.08.03