자바스크립트는 브라우저 환경 또는 Node.js 환경에서 실행할 수 있다.
Node.js는 화면에 렌더링하는 것이 주된 목적인 브라우저와 달리 브라우저 외부에서 자바스크립트 실행 환경을 제공하는 것이 주된 목적이다.
따라서 브라우저와 Node.js 모두 자바스크립트 코어인 ECMAScript를 실행할 수 있지만 Node.js에서 그 외의 추가 기능은 호환되지 않는다.
반대로 Node.js에서는 파일을 생성하고 수정할 수 있는 파일 시스템을 기본 제공하지만 브라우저는 이를 지원하지 않는다. 브라우저를 통해 사용자 컴퓨터의 로컬 파일을 삭제하거나 수정, 생성하는 것은 보안상의 이슈가 될 수 있기 때문이다.
브라우저에 기본 내장되어 있다!
브라우저는 HTML 파일을 로드하면 script 태그에 포함된 자바스크립트 코드를 실행한다.
콘솔 창에 나타난 에러 메세지의 에러 발생 위치 링크를 클릭하면 sources 패널로 이동한다. 에러가 발생한 위치에 빨간 밑줄이 표시된다. 에러가 발생한 코드 왼쪽의 라인 번호를 클릭하면 브레이크 포인트가 걸리고, 다시 버튼을 클릭하면 디버깅 모드로 들어간다.
프레임워크나 라이브러리를 도입하거나 바벨, 웹팩 등 여러 도구를 사용하려면 Node.js와 npm(자바스크립트 패키지 매니저)이 필요하다.
Node.js REPL(Read Eval Print Loop)를 사용하면 자바스크립트 코드를 실행해 결과를 확인해볼 수 있다.
자바스크립트 파일을 실행하려면 터미널에서 node filename을 입력하면 된다.
변수는 하나의 값을 저장하기 위해 확보한 메모리 공간 자체 또는 그 메모리 공간을 식별하기 위해 붙인 이름을 말한다. 즉, 프로그래밍 언어에서 값을 저장하고 참조하는 메커니즘이며 값의 위치를 가리키는 상징적인 이름이다.
변수 이름을 사용해 참조를 요청하면 자바스크립트 엔진은 변수 이름과 매핑된 메모리 주소를 통해 메모리 공간에 접근해 저장된 값을 반환한다.
식별자는 어떤 값을 구별해서 식별할 수 있는 고유한 이름을 말한다. 변수 이름을 식별자라고도 한다.
식별자는 값이 아니라 메모리 주소를 기억하고 있다. 즉, 식별자는 메모리 주소에 붙인 이름이라고 할 수 있다.
변수 선언은 값을 저장하기 위한 메모리 공간을 확보하고 변수 이름과 확보된 메모리 공간의 주소를 연결해서 값을 저장할 수 있게 준비하는 것이다.
변수를 사용하려면 반드시 선언이 필요하다. var, let, const 키워드를 사용한다.
let score; // 변수 선언(변수 선언문)
자바스크립트 엔진은 변수 선언을 다음과 같은 2단계에 거쳐 수행한다.
변수 이름을 비롯한 모든 식별자는 실행 컨텍스트에 등록된다. 실행 컨텍스트는 자바스크립트 엔진이 소스코드를 평가하고 실행하기 위해 필요한 환경을 제공하고 코드의 실행 결과를 실제로 관리하는 영역이다. 변수 이름과 변수 값은 실행 컨텍스트 내에 키/값 형식인 객체 형태로 등록되어 관리된다.
변수 선언은 런타임(소스코드가 한 줄씩 실행되는 시점)이 아니라 그 이전 단계에서 실행된다.
소스코드를 실행하기 위해 소스코드 평가 과정을 거치는데, 자바스크립트 엔진은 변수 선언을 포함한 모든 선언문을 소스코드에서 찾아내 먼저 실행하고 그 외 소스코드를 한 줄씩 순차적으로 실행한다.
이처럼 변수 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 자바스크립트 고유의 특징을 변수 호이스팅이라 한다.
할당 연산자 = 를 사용한다.
console.log(score) //undefined
let score = 80;
console.log(score) //80
변수 선언은 소스코드가 순차적으로 실행되는 시점인 런타임 이전에 먼저 실행되지만 값의 할당은 소스코드가 순차적으로 실행되는 시점인 런타임에 실행된다.
var과 let으로 선언한 변수는 값을 재할당할 수 있다. 재할당은 현재 변수에 저장된 값을 버리고 새로운 값을 저장하는 것이다. 만약 값을 재할당 할 수 없다면 변수가 아니고 상수다.
let score = 80
score = 90;
이와 같이 값을 할당하면 새로운 메모리 공간을 확보하고 그곳에 할당 값을 저장한다. 이렇게 되면 이전 값은 어떤 식별자와도 연결되어 있지 않다. 이러한 불필요한 값은 가비지 콜렉터에 의해 메모리에서 자동 해제된다. 단, 언제 해제될지는 예측할 수 없다.