Scope Chain

developer.do·2023년 5월 1일
0

Scope란?

  • 스코프(유효범위)는 참조 대상 식별자를 찾아내기 위한 규칙이다.
  • 전역 스코프 (Global scrope) : 말 그대로 전역(어디서든지)에서 참조할 수 있는 스코프이다.
  • 지역 스코프 (Local scrope = function level scope) : 함수 코드 블록이 만든 스코프로 함수 자신과 하위 함수에서만 참조가 가능하다.
  • 전역 변수 (Global variable) : 전역에서 선언된 변수로, 어디에서든 참조가 가능하다.
  • 지역 변수 (Local variable) : 지역(함수)내에서 선언된 변수로, 해당 지역과 그 지역의 하부 지역에서 참조가 가능하다.

다음은 지역변수와 전역변수에 대한 예시이다.


var x ="foo"; // 어디서든지 참조할 수 있다.

function hello(){
 var x = "poo"; // hello 함수 내부에서만 참조가 가능하다.
  console.log(x)
}


hello() // poo
console.log(x) // foo
var x = "foo"; // 전역변수이기 때문에 어디서든 사용이 가능하다.

function hello(){
var y = "poo"; // 지역변수이기 때문에 hello 함수 스코프 내에서 참조가 가능하다.
  console.log(x); // foo
  console.log(y); // poo
}
hello();


console.log(x); // foo
console.log(y) // Error

함수 레벨 스코프

자바스크립트는 함수 레벨 스코프를 사용하는데, 함수 내에서 선언된 변수는 함수 외부에서 유효하지 않다.

var x ="foo"; // 전역변수

function hello(){
 var y ="poo"; // 지역변수
}

console.log(x) // foo
console.log(y) // Error

전역변수 x와 지역변수 x가 중복 선언이 된 경우

전역 영역에서는 전역변수만 참조가 가능하다.
지역 영역에서는 지역변수전역변수 모두 참조가 가능하지만, 지역변수를 우선 참조한다.

var x ="foo";
function hello(){
 var x ="poo";
  console.log(x)
}
foo(); // poo
console.log(x); // foo

함수 내에 존재하는 내부 함수의 경우, 자신을 포함하고 있는 외부함수에 접근이 가능하다.

var x = "foo";

function hello(){ // 외부함수 hello
 var x ="poo";
  console.log(x)  // poo
  
 function bye(){  // hello 함수 내에 존재하는 내부함수인 bye 함수이다.
  console.log(x)  // poo, bye함수에서 참조하는 변수x는 hello함수에서 선언된 지역변수이다. 스코프 체인으로 인해 참조 순위가 지역변수 > 전역변수가 되었다.
 }
  bye()
}

hello()  
console.log(x) // foo

단 지역(함수) 영역에서는 전역변수를 참조할 수 있고, 값도 변경할 수 있다.

var x = 10; 

function hello(){
  x = 50;
  console.log(x) // 50
}
hello()
console.log(x) // 50

중첩 스코프는 가장 인접한 지역을 우선으로 참조한다.

var x = 10;

function foo(){
 var x = 100;
  console.log(x) // 100 
  
  function bar(){
   x = 1000; 
    console.log(x) // 1000
  }
  bar()
  
  
}

foo()
console.log(x) // 10

스코프 체인이란?

  • 자바스크립트 엔진은 식별자를 찾을 때, 우선 자신이 속한 스코프에서 찾는다.
    하지만 그 스코프에 식별자가 없다면 상위 스코프에서 다시 식별자를 찾는다.
    이러한 현상을 스코프 체인이라고 하며 스코프가 중첩되어있는 모든 상황에서 발생한다.
var x = 1;

function hello(){
    console.log(x); // 자신의 스코프인 hello 함수 내부에 x가 없지만, 
                    // 스코프 체인으로 인하여 상위 스코프인 전역에서 x를 찾을 수 있다.
}

console.log(x); // 1
hello(); // 1

렉시컬 스코프란?

  • 스코프 체인렉시컬 스코프를 기반으로 한다.
    여기서 렉시컬 스코프란 코드를 작성할 때 변수가 어떤 스코프에 속하는지 결정되는 것을 말한다.
    즉 변수가 선언된 위치에서부터 스코프가 결정이 되며 변수가 선언된 함수나 블록의 스코프에서만 접근이 가능하다.
function outer(){
  
 var x ="poo";
  function inner(){
   console.log(x);
  }
  inner();  // inner 함수에는 x가 없기 때문에 상위 스코프인 outer 함수의 x를 참조한다.
  
}

outer(); // poo

클로저란?

  • 스코프 체인클로저 구현에 중요한 역할을 한다.
    여기서 클로저란 함수가 선언될 당시 렉시컬 스코프를 기억하는 함수이다.
    클로저는 자신이 선언된 스코프를 벗어난 곳에서 호출을 해도 해당 스코프의 변수에 접근할 수 있다.
    이것은 바로 스코프 체인이 형성되어 있기 때문이다.
    따라서 클로저는 상위 스코프의 변수를 계속해서 사용할 수 있다.
function outer(){
	let name = 'frank';

	function inner(){  // inner 함수에는 변수 name이 없기 때문에 상위 스코프인 outer 함수의 name을 참조한다.
		console.log(`hello! ${name}`); // hello frank
	}

	inner();

	return inner;
}

let greeting = outer()
greeting() // greeting 변수에는 inner 함수가 담겨있기 때문에 outer 함수가 이미 종료되어도 
           // 여전히 name 변수에 접근을 해서 hello frank가 나오는 것을 확인 할 수 있다

이처럼 어떤 함수를 렉시컬 스코프 밖에서 호출해도, 원래 선언되었던 렉시컬 스코프를 기억하고 접근 할 수 있는 특성을 클로저라고 한다.

0개의 댓글