스코프

모든 식별자는 선언된 위치에 의해 참조할 수 있는 유효 범위가 결정되는데, 이 유효범위를 스코프라고 한다. 

같은 이름의 변수 할당 후 출력 확인 코드 

var n = 'globalVar'

function test(){
  var n = 'localVar';
  console.log(n);     // 1번
}

test();
console.log(n);       // 2번

이름 같은 두 개의 변수가 있다면 자바스크립트는 어떤 변수를 참조해야 할지 결정을 해야하는데 이 과정을 식별자 결정이라 한다.

이때 엔진은 스코프를 통해 결정하는데, 또한 코드의 문맥을 고려하기 때문에 1,2번 다른 출력이 나오게 된다. 

localVar
globalVar

어떻게 둘의 출력이 다르게 나오는가 하면, 가장 바깥에서 선언된 n변수는 코드 안 어디서든 참조할 수 있게되고, test라는 함수내에서 지금 선언된 n변수는 같은 이름의 식별자지만,  스코프가 다른 관계를 별개의 변수로 취급되서 다른출력이 나옵니다.


let과 const라는 키워드는 var의 단점을 보완하기 위해 나온것이다.

var 키워드의 변수 중복 선언

function test(){
  var n = 4;

  var n = 2;
  console.log(n);
}

test();  // 2

var 키워드로 선언한 변수는 위에서 보다 싶이 스코프 내에서 중복 선언이 허용이 됩니다. 이렇다면 변수의 값이 재할당되어 바뀔 수 있는 부작용이 있기때문에, 이 점을 let, const에서 보완을 했고 var와 다르게 이미 선언됬다는 경고문을 알려줍니다.

 

var 키워드의 변수 유효범위 

var age = 21;
if(age >= 19){
  var result = true;
}
console.log(result); // true

그리고 var 키워드는 변수의 유효범위가 함수 스코프이기 때문에  함수 내부 이외에 생성한 변수는 모두 전역 변수가 되어 남발하기 쉽상이지만 let, const는  블록 스코프부터 이기때문에 let사용을 좀더 권한다. 

 


스코프 체인 ( Scope Chain )

모든 스코프는 하나의 계층적 구조로 연결되고, 스코프가 계층적으로 연결된 것을 스코프 체인(Scope Chain)이라고 한다.

 

 

 

변수를 참조할 때 자바스크립트 엔진은 스코프 체인을 통해 변수를 참조하는 코드의 스코프에서 시작해서 상위 스코프 방향으로 이동하며 선언된 변수를 검색한다. 

 

 

 

 


렉시컬 스코프 ( Lexical Scope )

함수를 어디서 호출했는지가 아닌, 함수가 어디서 정의했는지에 따라 상위 스코프를 결정하는 것을 말함 
let name = "Evan";

function nam(){
  let name = "Jeongmin"
  namae();
}

function namae(){
  console.log(name);
}

nam();
namae();

위에 코드를 보면 출력이 어떻게 나올 것 같으신가요 ?   여기서 두가지 패턴이 나옵니다.  

1. 동적 스코프 : 함수를 어디서 호출했는지를 기준으로 상위 스코프를 결정하는 것. 

2. 렉시컬 스코프 : 함수를 어디서 정의했는지를 기준으로 상위 스코프를 결정하는 것.

 

주제를 보면 눈치챘겠지만 결과는 렉시컬 스코프를 기준으로 동작이되서 출력은 namae 함수가 정의된 곳 기준인 "Evan"이  출력되게 된다. 자바스크립트를 비롯한 대부분의 프로그래밍 언어는 렉시컬 스코프를 따른다.