1주차
04.변수
4-1. 변수란 무엇인가? 왜 필요한가?
메모리는 데이터를 저장할 수 있는 메모리 셀의 집합체다. 메모리 셀 하나의 크기는 1바이트(8비트)이며, 컴퓨터는 메모리 셀의 크기, 즉 1바이트 단위로 데이터를 저장하거나 읽어들인다.
컴퓨터는 모든 데이터를 2진수로 처리한다. 따라서 메모리에 저장되는 데이터는 데이터의 종류(숫자, 텍스트, 이미지, 동영상 등)와 상관없이 모두 2진수로 제공된다.
프로그래밍 언어는 기억하고 싶은 값을 메모리에 저장하고, 저장된 값을 읽어 들여 재사용하기 위해 변수라는 메커니즘을 제공한다.
변수
변수는 하나의 값을 저장하기 위해 확보한 메모리 공간 자체 또는 그 메모리 공간을 식별하기 위해 붙인 이름을 말한다. 값의 위치를 가리키는 상징적인 이름이다.
var result = 10 + 20;
위의 예제에서는 result가 변수 이름 또는 변수명, 30이 변수에 저장된 값 또는 변수 값이라고 한다.
4-2. 식별자
식별자
변수이름을 식별자라고도 한다. 식별자는 어떤 값을 구별해서 식별할 수 있는 고유한 이름을 말한다. 식별자는 값이 아니라 메모리 주소를 기억하고 있다.
변수, 함수, 클래스 등의 이름과 같은 식별자는 네이밍 규칙을 준수해야 하며, 선언에 의해 자바스크립트 엔진에 식벼자의 존재를 알린다.
4-3. 변수 선언
변수를 사용하려면 반드시 선언이 필요하다. 변수를 선언할 때는 var, let, const 키워드를 사용한다.
var 키워드에는 여러 단점이 있다. var 키워드의 여러 단점 중에서 가장 대표적인 것이 블록 레벨 스코프를 지원하지 않고 함수 레벨 스코프를 지원한다는 것이다. 이로 인해 의도치 않게 전역 변수가 선언되어 심각한 부작용이 발생하기도 한다.
var 키워드를 사용한 변수 선언은 선언 단계와 초기화 단계가 동시에 진행된다. var score;는 선언 단계를 통해 변수 이름 score를 등록하고, 초기화 단계를 통해 score 변수에 암묵적으로 undefined를 할당해 초기화 한다.
4-4. 변수 선언의 실행 시점과 변수 호이스팅
console.log(score); //undefined
var score; // 변수 선언문
console.log(score);가 실행되는 시점에는 아직 score 변수의 선언이 실행되지 않았으므로 참조 에러가 발생할 것처럼 보인다. 하지만 참조 에러가 발생하지 않고 undefined가 출력된다.
그 이유는 변수 선언이 소스코드가 한 줄 씩 순차적으로 실행되는 시점, 즉 런타임이 아니라 그 이전 단계에서 먼저 실행되기 때문이다.
이처럼 변수 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 자바스크립트 고유의 특징을 변수 호이스팅이라 한다.
4-5. 값의 할당
변수에 값을 할당(대입, 저장)할 때는 할당 연산자 =를 사용한다. 할당 연산자는 우변의 값을 좌변의 변수에 할당한다.
console.log(score); // undefined
var score; // 1. 변수 선언
score = 80; // 2. 값의 할당
console.log(score); //80
1. 변수 선언은 소스코드가 순차적으로 실행되는 시점인 런타임 이전에 먼저 실행되지만 2. 값의 할당은 소스코드가 순차적으로 실행되는 시점인 런타임에 실행된다.
4-6. 값의 재할당
var score = 80; // 변수 선언과 값의 할당
score = 90; // 값의 재할당
var 키워드로 선언한 변수는 값을 재할당할 수 있다. 만약 값을 재할당할 수 없어서 변수에 저장된 값을 변경할 수 없다면 변수가 아니라 상수라 한다.
4-7. 식별자 네이밍 규칙
- 식별자는 특수문자를 제외한 문자, 숫자, 언더스코어(_), 달러 기호($)를 포함할 수 있다.
- 단, 식별자는 특수문자를 제외한 문자, 언더스코어(_), 달러기호($)로 시작해야한다. 숫자로 시작하는 것은 허용하지 않는다.
- 예약어는 식별자로 사용할 수 없다.
네이밍 컨벤션은 하나 이상의 영어 단어로 구성된 식별자를 만들 때 가독성 좋게 단어를 한눈에 구분하기 위해 규정한 명명 규칙이다.
// 카멜 케이스(camelCase)
var firsName;
// 스네이크 케이스(snake_case)
var first_name;
// 파스칼 케이스(PascalCase)
var FirstName;
// 헝가리안 케이스(typeHungarianCase)
var strFirstName;
var $elem = document.getElemnetById('myId'); // DOM 노드
var observable$ = fromEvent(document, 'click'); // RxJS 옵저버블
자바스크립트에서는 일반적으로 변수나 함수의 이름에는 카멜 케이스를 사용하고, 생성자 함수, 클래스의 이름에는 파스칼 케이스를 사용한다.
5장. 표현식과 문
5-1. 값
값은 식(표현식)이 평가되어 생성된 결과를 말한다.
변수는 하나의 값을 저장하기 위해 확보한 메모리 공간 자체 또는 그 메모리 공간을 식별하기 위해 붙인 이름이므로 변수에 할당되는 것은 값이다.
// 변수에는 10 + 20이 평가되어 생성된 숫자 30이 할당된다.
var sum = 10 + 20
5-2. 리터럴
리터럴
- 리터럴은 사람이 이해할 수 있는 문자 또는 약속된 기호를 사용해 값을 생성하는 표기법을 말한다.
- 리터럴 종류와 예시 p.52 표 참고
5-3. 표현식
표현식
표현식은 값으로 평가될 수 있는 문이다. 즉, 표현식이 평가되면 새로운 값을 생성하거나 기존 값을 참조한다.
// 리터럴 표현식
10
'Hello'
// 식별자 표현식 (선언이 이미 존재한다고 가정)
sum
person.name
arr[1]
// 연산자 표현식
10 + 20
sum = 10
sum !== 10
// 함수/메서드 호출 표현식 (선언이 이미 존재한다고 가정)
square()
person.getName()
5-4. 문
문
문은 프로그램을 구성하는 기본 단위이자 최소 실행 단위 이다. 문은 여러 토큰으로 구성된다.
토큰
토큰이란 문법적인 의미를 가지며, 문법적으로 더 이상 나눌 수 없는 표현식의 기본 요소를 의미한다.
5-5. 세미콜론과 세미콜론 자동 삽입 기능
세미콜론(;)은 문의 종료를 나타낸다. 단 0개 이상의 문을 중괄호로 묶은 코드 블록 ({...}) 뒤에는 세미콜론을 붙이지 않는다. 코드 블록은 언제나 문의 종료를 의미하는 자체 종결성을 갖기 때문이다.
이처럼 문의 끝이라고 에측되는 지점에 세미콜론을 자동으로 붙여주는 기능을 세미콜론 자동 삽입 기능(ASI) 라고 한다.
5-6. 표현식인 문과 표현식이 아닌 문
// 변수 선언문은 값으로 평가할 수 없으므로 표현식이 아니다.
var x;
// 1, 2, 1 + 2, x = 1 + 2는 모두 표현식이다.
// x = 1 + 2는 표현식이면서 완전한 문이기도 하다.
x = 1 + 2;
표현식인 문과 표현식이 아닌 문을 구별하는 가장 간단하고 명료한 방법은 변수에 할당해 보는 것 이다.
06장. 데이터 타입
데이터 타입은 값의 종류를 말한다. 자바스크립트의 모든 값은 데이터 타입을 갖는다. p.59 데이터 타입 종류 참고
6-1. 숫자 타입
- 자바스크립트는 하나의 숫자 타입만 존재한다.
- 정수만의 타입이 없고 모든 수를 실수로 처리한다.
var integer = 10; // 정수
var double = 10.12; // 실수
var negative = -20; // 음의 정수
var binary = 0b01000001; // 2진수
var octal = 0o101; // 8진수
var hex = 0x41; // 16진수
// 숫자 타입은 모두 실수로 처리된다.
console.log(1 === 1.0); //true
console.log(4 / 2); // 2
// 숫자 타입의 세 가지 특별한 값
console.log(10 / 0); // Infinity
conoole.log(1 + 'String'); // NaN
6-2. 문자열 타입
- 문자열 타입은 텍스트 데이터를 나타내는 데 사용한다.
- 문자열은 작은따옴표(''), 큰따옴표(""), 또는 백틱(``)으로 텍스트를 감싼다.
- 만약 문자열을 따옴표로 감싸지 않으면 자바스크립트 엔진은 키워드나 식별자 같은 토큰으로 인식한다.
6-3. 템플릿 리터럴
- ES6부터 템플릿 리터럴이라고 하는 새로운 문자열 표기법이 도입되었다.
- 멀티라인 문자열, 표현식 삽입, 태그드 템플릿 등 편리한 문자열 처리 기능을 제공한다.
- 일반 문자열과 비슷해 보이지만 작은따옴표('') 또는 큰따옴표("") 같은 일반적인 따옴표 대신 백틱(``)을 사용해 표현한다.
var templete = 'Template Literal'; console.log('templete); // Template literal
멀티라인 문자열
- 일반 문자열 내에서는 줄바꿈(개행)이 허용되지 않는다.
- p.63 이스케이프 시퀀스 종류 표 참고
- 일반 문자열과 달리 템플릿 리터럴 내에서는 이스케이프 시퀀스를 사용하지 않고도 줄바꿈이 허용되며 공백도 있는 그대로 적용된다.
// 줄바꿈과 들여쓰기가 적용된 HTML 문자열
var template = '<ul>\n\t<li><a href="#">Home</a></li>\n<ul>';
console.log(template);
// 출력 결과
<ul>
<li><a href="#">Home</a></li>
</ul>
표현식 삽입
- 문자열은 문자열 연산자 +를 사용해 연결할 수 있다.
- 템플릿 리터럴 내에서는 표현식 삽입을 통해 간단히 문자열을 삽입 할 수 있다.
var first = 'Ung-mo';
var last = 'Lee';
// 표현식 삽입
console.log('My name is ${first} ${last}.');
- 이때 표현식의 평가 결과가 문자열이 아니더라도 문자열로 타입이 강제로 변환되어 삽입된다.
- 표현식 삽입은 받느시 템플릿 리터럴 내에서 사용해야 한다.
6-4. 불리언 타입
- 불리언 타입의 값은 논리적 참, 거짓을 나타내는 true와 false뿐이다.
- 불리언 타입의 값은 참과 거짓으로 구분되는 조건에 의해 프로그램의 흐름을 제어하는 조건문에서 자주 사용한다.
6-5. undefined 타입
- undefined 타입의 값은 undefined가 유일하다.
- var 키워드로 선언한 변수는 암묵적으로 undefined로 초기화된다.
- 자바스크립트 엔진이 변수를 초기화하는데 사용하는 undefined를 개발자가 의도적으로 변수에 할당한다면 undefined의 본래 취지와 어긋날뿐더러 혼란을 줄 수 있으므로 권장하지 않는다. 이런 경우에는 undefined 대신 null을 할당한다.
6-6, null 타입
- null 타입의 값은 null이 유일하다.
- 프로그래밍 언어에서 null은 변수에 값이 없다는 것을 의도적으로 명시할 때 사용한다.
6-7. 심벌 타입
- 심벌은 변경 불가능한 원시 타입의 값이다.
- 다른 값과 중복되지 않는 유일무이한 값이다.
- 주로 이름이 충돌할 위험이 없는 객체의 유일한 프로퍼티 키를 만들기 위해 사용한다.
// 심벌 값 생성
var key = Symbol('key');
console.log(typeof key); //symbol
// 객체 생성
var obj = {};
// 이름이 충돌할 위험이 없는 유일무이한 값인 심벌을 프로퍼티 키로 사용한다.
obj[key] = 'value';
console.log(obj[key]); // value
6-8. 객체 타입
자바스크립트는 객체 기반의 언어이며, 자바스크립트를 이루고 있는 거의 모든 것이 객체라는 것이다.
6-9. 데이터 타입의 필요성
데이터 타입에 의한 메모리 공간의 확보와 참조
값은 메모리에 저장하고 참조할 수 있어야 한다.
var a = 100;
var b = 100;
0x123 : 100
0x123 : 식별자 a, 값은 0x123
0x123 : 식별자 b, 값은 0x123
b = 111;
0x124 : 111
0x112 : 식별자 b, 값은 0x124
데이터 타입에 의한 값의 해석
자바스크립트의 모든 값은 데이터 값을 갖는다. 데이터 타입이 필요한 이유는
- 값을 저장할 때 확보해야 하는 메모리 공간의 크기를 결정하기 위해
- 값을 참조할 때 한번에 읽어 들여야 할 메모리 공간의 크기를 결정하기 위해
- 메모리에서 읽어 들인 2진수를 어떻게 해석할지 결정하기 위해
6-10. 동적 타이핑
동적 타입 언어와 정적 타입 언어
- c나 자바 같은 정적 타입 언어는 변수를 선언할 때 변수에 할당할 수 있는 값의 종류, 즉 데이터 타입을 사전에 선언해야 한다. 이를 명시적 타입 선언이라 한다.
- 자바스크립트, 파이썬, PHP, 루비, 리스프, 펄 등과 같은 경우 변수 선언이 아닌 할당에 의해 타입이 결정된다. 그리고 재할당에 의해 변수의 타입은 언제든지 동적으로 변할 수 있다. 이러한 특징을 동적 타이핑이라 하며, 동적 타입 언어라고 한다.
var foo;
console.log(typleof foo); // undefined
foo = 3;
console.log(typleof foo); // number
foo = 'Hello';
console.log(typleof foo); // string
foo = true;
console.log(typleof foo); // boolean
foo = Symbol();
console.log(typleof foo); // symbol
foo = {};
console.log(typleof foo); // objeect
foo = [];
console.log(typleof foo); // object
foo = function() {};
console.log(typleof foo); // function
동적 타입 언어와 변수
동적 타입 언어는 변수에 어떤 데이터 타입의 값이라도 자유롭게 할당할 수 있다. 이러한 동적 타입 언어의 특징은 데이터 타입에 대해 무감각해질 정도로 편리하다는 것이다. 하지만 편리함의 이면에는 위험도 도사리고 있다.
변수를 사용할 때 주의사항
- 변수는 꼭 필요한 경우에 한해 제한적으로 사용한다.
- 변수의 유효 범위(스코프)는 최대한 좁게 만들어 변수의 부작용을 억제한다.
- 전역 변수는 최대한 사용하지 않도록 한다.
- 변수보다는 상수를 사용해 값의 변경을 억제한다.
- 변수 이름은 변수의 목적이나 의미를 파악할 수 있도록 네이밍한다.
'🎒내가방 > 📒JavaScript' 카테고리의 다른 글
[모던 자바스크립트 Deep Dive] 12장 함수 (1) | 2023.06.12 |
---|---|
[모던 자바스크립트 Deep Dive] 13장 스코프 (0) | 2023.06.10 |
[모던 자바스크립트 Deep Dive] 11장 원시 값과 객체의 비교 (0) | 2023.06.10 |
[모던 자바스크립트 Deep Dive] 10장 객체 리터럴 (0) | 2023.06.08 |
[프로그래머스] LV.1 - 자릿수 더하기 (0) | 2023.05.15 |