scope의 사전적인 의미는 범위이다. 자바스크립트에서 스코프란 작성된 코드를 둘러싼 환경으로, 어떤 변수들에 접근할 수 있는지를 정의이다. 어떤 범위 내에 속해있는지를 정의한다고 생각하면 사전적 의미와 유사하다고 할 수 있어 스코프는 전역(global)과 지역(local) 스코프로 정의할 수 있다.
호이스팅은 코드가 실행하기 전 변수선언/함수선언이 해당 스코프의 최상단으로 끌어 올려진 것 같은 현상을 말한다.
호이스팅이라는 용어를 자바스크립트 실행 컨텍스트에 의한 위에 설명한 현상을 호이스팅이라고 부른다는 것으로 이해하면 되겠다. 그 현상이란 선언이 코드 실행 보다 먼저 메모리에 저장되는 과정으로 인한 현상을 말한다. 그래서 자바스크립트 실행 컨텍스트에 대한 이해하는 것이 호이스팅을 이해하는데 도움이 된다. (scope, hoisting, this, function, closure 등의 동작원리를 담고 있는 자바스크립트 핵심원리이다. 코드를 보고 실행 컨텍스트를 이해할 수 있어야 코드 독해, 디버깅을 할수 있다.
TDZ(Temporal Dead Zone) 란, 한글로 직역하자면 일시적인 사각지대란 뜻입니다.
이 일시적인 사각지대는 스코프의 시작 지점부터 초기화 시작 지점까지의 구간을 TDZ(Temporal Dead Zone) 라고합니다.
먼저, 함수 선언문(function declartion)은 함수명이 정의되어 있고,
function sum(a,b) {
return a + b;
}
별도의 할당 명령이 없는것이고 함수 표현식은(function Expression) 정의한 function을 별도의 변수에 할당하는 것
const sum = function(a,b) {
return a + b;
}
주요 차이점은 호이스팅에서 차이가 난다. 함수 선언식
은 함수 전체를 호이스팅 한다 그래서 정의된 범위의 맨 위로 호이스팅되서 함수 선언 전에 함수를 사용할 수 있다. 반면 함수표현식
은 별도의 변수에 할당하게 되는데 변수는 선언부와 할당부를 나누어 호이스팅하게 된다 즉 선언부만 호이스팅하게된다.
var 특징
var는 기존의 변수 선언 방식이다
전역 스코프이므로 전역변수로 선언된 경우 모든 곳에서 사용이 가능하다.
함수 스코프다. 함수 내에 선언된 경우 함수 범위 내에서만 사용 가능하다
변수 재선언과 수정이 가능하다
변수 선언후에 사용이 가능하다
장점 : 간단한 테스트 시에 편리하다
단점 : 코드가 복잡해질수록 어디에 사용되는지 파악하기 힘들다
let 특징
let 변수는 var 변수를 개선한 버전이다
블록 스코프이다. {블록} 안에서만 가능하다
블록 밖에서 호출하면 에러가 나온다
변수 재선언이 불가능하지만 수정은 가능하다
서로 다른 블록에 같은 이름으로 선언 가능하다(겹치지않는다면)
변수 선언 후에 사용 가능하다
Const 특징
let과 동일하지만 값을 수정할 수 없다느 차이점이 있다.
객체의 속성은 수정할 수없지만 값은 수정할 수 있다
function 특징
함수(function)란 하나의 특별한 목적의 작업을 수행하도록 설계된 독립적인 블록을 의미한다. 이러한 함수는 필요할 때마다 호출하여 해당 작업을 반복해서 수행할 수 있다.
자바스크립트에서 함수의 정의는 function 키워드로 시작되며, 다음과 같은 구성요소를 가집니다.
실행 컨텍스트(Execution context)는 우리가 작성한 코드가 실행되는 환경을 말하며, scope, hoisting, this, function, closure 등의 동작원리를 담고 있는 자바스크립트의 핵심원리를 말한다.
*Call stack 이란?
js 엔진은 생성된 Context를 관리하는 목적의 Call Stack(호출스택)을 갖고 있다. JS는 단일 스레드 형식이기 때문에 런타임에 단 하나의 Call Stack이 존재한다. js 엔진은 전역 범위의 코드를 실행하며 Global Execution Context를 생성해 stack에 push한다. 그리고 함수가 실행 또는 종료 될 때마다 Global Execution Context의 위로 Functional Execution Context stack을 push(추가), pop(제거)한다
스코프 체인(Scope Chain)은 일종의 리스트로서 전역 객체와 중첩된 함수의 스코프의 레퍼런스를 차례로 저장하고, 의미 그대로 각각의 스코프가 어떻게 연결(chain)되고 있는지 보여주는 것을 말한다
(function () {
var a = 'a';
})();
console.log(a); // a is not defined
함수 외부에서 a를 출력해보면, 아직 정의되지 않았다(a is not defined)는 에러메세지를 확인할 수 있습니다. 이러한 방식과 같이 직접적으로 변경되면 안 되는 변수에 대한 접근을 막는 것을 은닉화라고 합니다.