현재 '모던 자바스크립트 Deep Dive'를 통해 자바스크립트를 학습하고 있습니다. 본 포스트는 해당 내용에 대한 정리를 목적으로 합니다.
자바스크립트 엔진이 10 + 20이라는 식의 의미를 해석하면 + 연산을 수행하기 위해 먼저 + 연산자의 좌변화 우변의 숫자 값, 즉 피연산자를 기억한다. CPU를 사용해 연산하고, 메모리를 사용해 데이터를 기억한다.
여기서, 메모리는 데이터를 저장할 수 있는 메모리 셀의 집합체다.
메모리 셀 하나의 크기는 1바이트(8비트)이며, 컴퓨터는 메모리 셀의 크기, 즉 1바이트 단위로 데이터를 저장하거나 읽어들인다.
각 셀은 고유의 메모리 주소를 갖는다. 0부터 시작해 메모리의 크기만큼 정수로 표현된다. 예를 들어, 4GB 메모리는 0부터 4,294,967,295(0x00000000 ~ 0xFFFFFFFF)까지의 메모리 주소를 갖는다.
(컴퓨터는 모든 데이터를 2진수로 처리한다. 여기서는 편하게 정수로 표현하겠습니다.!)
메모리는 여기까지 정리하겠습니다.
변수는 하나의 값을 저장하기 위해 확보한 메모리 공간 자체 또는 그 메모리의 공간을 식별하기 위해 붙인 이름이다.!
변수에 값을 저장하는 것을 할당이라고 하며 변수 저장된 값을 읽어들이는 것을 참조라고 한다.
변수 이름을 식별자라고도 한다. 식별자는 어떠한 값을 구별해서 식별할 수 있는 고유한 이름을 말한다.
식별자는 값이 아니라 메모리 주소를 기억하고 있다.
result ---------------> 0x0669F913 [30]
변수이름(식별자)-------메모리 주소----메모리
변수 선언이란 변수를 생성하는 것을 말한다. 자세히 얘기하자면 값을 저장하기 위한 메모리 공간을 확보하고 변수이름과 확보된 메모리 공간의 주소를 연결해서 값을 저장할 수 있게 준비하는 것이다.
변수를 사용하려면 반드시 선언이 필요하다. 선언할 때는 var, let, const 키워드를 사용한다.
var키워드는 단점이 있다. 블록 레벨 스코프를 지원하지 않고 함수 레벨 스코프를 지원한다는 것이다. 의도치 않게 전역 변수가 선언되어 심각한 부작용이 발생한다. 현재는 let, const만 사용하는 것이 좋겠다.!
선언에는 단계가 2개 있다.
1. 선언단계 : 변수를 선언하여 자바스크립트 엔진에 변수 존재를 알린다.
2. 초기화 단계 : 변수를 선언하면 자바스크립트 엔진은 undefined 할당해 초기화 한다. undefined 할당하는 것은 자바스크립트의 독특한 특징이다.
여기서 중요한 포인트는 var키워드로 선언하였을때만 undefined 할당해 초기화 하는 것이다. let, const는 undefined 할당해 초기화가 되지 않는다. 이 이유는 나중에 설명하겠습니다.
변수 선언의 실행 시점은 우선 코드가 한줄씩 실행되는 런타임 과정이 아닌, 런타임 이전에 실행이 된다.
console.log(score); // undefined
var score = 10;
위에 코드는 참조에러가 나지 않는다. 이유는 var키워드를 이용하여 변수를 선언하면 자바스크립트 엔진이 undefined 할당해 초기화 되기 때문에 에러가 나지 않고, 변수 선언은 런타임 과정이 아닌, 런타임 이전에 실행되어 score라는 변수는 undefined 할당 된 상태로 코드 런타임이 실행되므로, 런타임 과정중에 console.log(score)를 만나게 되면 undefined가 출력이 된다.
이 현상은 변수 호이스팅이라고 하는데 변수 선언문이 코드 선두로 끌어 올려진 것 처럼 동작하는 자바스크립트 고유의 특징이다.
그렇기 때문에 참조에러(Reference Error)가 발생하지 않고 undefined 출력되는 것이다.
값의 할당이란 우변의 값을 좌변의 변수에 할당(대입)한다는 것을 의미한다.
var score; // 변수 선언
score = 10; // 값의 할당
// 변수 선언과 값의 할당을 하나의 문(statement)로 단축 표현할 수도 있다.
var score = 10; // 변수 선언과 값의 할당
console.log(score); // undefined
var score;
score = 80;
console.log(score); // 80
변수를 선언하면 런타임 이전에 undefined 할당하고 초기화 한다. 런타임 과정에서 첫 번째 console.log(score); 는 undefined 출력을 한다. 다음으로 score = 80; 이라는 값을 할당했다. 이전에 저장되어있던 메모리 공간을 지우고 그 메모리 공간에 할당 값 80을 저장하는 것이 아니라 새로운 메모리 공간을 확보하고 그곳에 할당 값 80을 저장한다. 할당을 하고 난 후 console.log(score);를 찍어보면 80이 출력된다.
재할당이란 이미 값이 할당되어 있는 변수에 새로운 값을 또 다시 할당하는 것을 말한다.
var score = 80; // 변수 선언과 값의 할당
score = 90; // 값의 재할당
만약, 값을 재할당할 수 없어서 변수에 저장된 값을 변경할 수 없다면 변수가 아니라 상수라 한다. 상수는 한번 정해지면 변하지 않는 것이다.
사진을 다시보면 score = 90으로 재할당 하였다. 이때 그러면 이전 값인 undefined와 80은 어떠한 식별자와도 연결되어 있지 않는다. 더 이상 필요하지 않는 값들이다. 이러한 불필요한 값들은 가비지 콜렉터에 의해 메모리에서 자동으로 해제가 된다.
가비지 콜렉터
가비지 콜렉터는 애플리케이션이 할당한 메모리 공간을 주기적으로 검사하여 더이상 사용하지 않는 메모리 공간을 해제하는 기능을 말한다. 더 이상 어떤 식별자도 참조하지 않는 메모리 공간을 의미한다. 해제하는 타이밍은 알 수 가 없다.
식별자는 어떤 값을 구별해서 식별해낼 수 있는 고유한 이름이다. 식별자는 다음과 같은 네이밍 규칙을 준수해야한다.
1. 문자, 숫자, 언더스코어(_), 달러 기호($)를 포함할 수 있다.(언더스코어, 달러기호를 제외한 특수문자는 불가능하다.)
2. 숫자로 시작하는 것은 허용하지 않는다.
3. 예약어는 식별자로 사용할 수 없다.
밑에 코드는 식별자로 사용할 수 없다.
var first-name; // -특수문자는 사용할 수 없다.
var 1st; // 숫자로 시작하는 것은 허용하지 않는다.
var this; // 예약어는 식별자로 사용할 수 없다.
식별자는 대소문자를 구분하기 때문에 아래 코드는 다 개별 식별자이다.
var firstname;
var firstName;
var FIRSTNAME;
변수 이름은 변수의 존재 목적을 쉽게 이해할 수 있도록 의미를 명확히 표현해야 한다. 좋은 변수 이름은 코드의 가독성을 높인다. 주석이 필요하다면 변수의 존재 목적을 명확히 드러내지 못하는 것이다.
var x = 3; // x 변수가 의미하는 바를 알 수 없다.
var score = 100; // score 변수는 점수를 의미한다.
네이밍 컨벤션은 하나 이상의 영어 단어로 구성된 식별자를 만들 때 가독성 좋게 단어를 한눈에 구분하기 위해 규정한 명명 규칙이다. 4가지 유형의 네이밍 컨벤션이 자주 사용된다.
// 카멜 케이스(camelCase)
var firstName;
// 스네이크 케이스(snake_case)
var first_name;
// 파스칼 케이스(PascalCase)
var FirstName;
// 헝가리언 케이스(typeHungarianCase)
var strFirstName; // type + identifier
var $elem = document.getElementById('myId'); // DOM 노드
var observable$ = fromEvent(document, 'click'); // RxJS 옵저버블
자바스크립트에서는 일반적으로 변수나 함수의 이름에는 카멜 케이스를 사용하고, 생성자 함수, 클래스의 이름에는 파스칼 케이스를 사용한다.
오늘 이렇게 책 내용을 토대로 정리해 보았는데 처음에는 되게 어려운 느낌이었는데 몇번 읽고 하나씩 이해가 되니 뒤에도 이해가 되기 시작했다. 앞으로 꾸준히 읽어가며 블로그에 작성해보겠습니다!! 파이팅
틀린 내용이 있다면 언제든 댓글로 피드백 부탁드립니다.! 감사합니다.!