스코프(scope)와 호이스팅(hoisting)

표정민·2020년 6월 19일
1
post-thumbnail

javascript의 스코프(scope)와 호이스팅(hoisting)에 대하여 알아보도록 하자.


🥠 스코프(scope)

javascript에서 scope(스코프)란 변수의 유효범위 라고 할 수 있으며 var는 함수 스코프, let과 const는 블록스코프를 갖는다.

var a = 1;

function output() {
	var a = 2;
	console.log(a);
}

output(); // output : 2
console.log(a); // output : 1

위의 예제에서 output라는 함수 안의 console.log(a);는 a를 출력하기위해 자신의 함수 스코프 안에서 변수 a가 있는지 확인하고 있을 경우 var a = 2;를 참조해 2를 출력하게 된다.
만약 output라는 함수 안의 var a = 2;가 없을경우 상위에 할당 되어 있는 var a = 1;를 참조하여 1을 출력하게 된다. 전역에 있는 console.log(a);는 전역 변수인 var a = 1;를 참조하여 1을 출력한다.

아래 예제를 살펴보자.

var a = 1;

function output() {
	var a = 2;
	function print(){
		console.log(a);
	}
	return print();
}

output(); // output : 2

output함수 내부 함수인 print함수의 console.log(a);는 자신의 함수 스코프 안에서 a가 있는지 확인하고 없을경우 상위 함수인 output함수의 var a = 2;를 참조하여 2를 출력 하게 된다.

var pyo = 'jung min';
for (var pyo = 0; pyo < 5; pyo++) {
	// loop
}

console.log(pyo); // output : 4

위의 예제에서 4가 출력되는 것을 확인할 수 있다.
var는 함수 스코프 단위로 유효하기 때문에 위와 같이 변수가 덮어씌워지는 문제가 발생한다 이를 해결하기 위해서는 아래와 같이 블록 스코프를 지원하는 let, const를 사용해야 한다

var pyo = 'jung min';
for (let pyo = 0; pyo < 5; pyo++) {
	// loop
}

console.log(pyo); // output : jung min

🥠 호이스팅(hoisting)

호스팅(hoisting)은 변수의 선언문을 유효범위의 최상단으로 끌어올리기로 해석할 수 있다.

if (true) {
	var pyo = 'min';
}

output1(); // output : jung min
output2(); // output : 4
console.log(pyo); // output : min

function output1() {
	if (true) {
		var pyo = "jung min";
	}
	console.log(pyo);
}

function output2() {
	for (var pyo = 0; pyo < 5; pyo++) {
		// loop
	}
	console.log(pyo);
}


// 호이스팅으로 변환된 코드
var pyo;

function output1() {
  	var pyo;
	if (true) {
		pyo = "jung min";
	}
	console.log(pyo);
}

function output2() {
  	var pyo;
	for (pyo = 0; pyo < 5; pyo++) {
		// loop
	}
	console.log(pyo);
}

if (true) {
	pyo = 'min';
}

output1(); // output : jung min
output2(); // output : 5
console.log(pyo); // output : min

위의 예제에서 확인할 수 있듯이 변수 및 함수를 유효범위 내부의 최상단으로 위치하게 됩니다.

🥠 함수 선언식과 표현식에 따른 호이스팅(hoisting)

🥠 함수 선언식

output1(); // output : jung min
function output1() {
	console.log('jung min');
}


// 호이스팅으로 변환된 코드
function output1() {
	console.log('jung min');
}
output1(); // output : jung min

선언식의 경우 호이스팅이 발생해 함수를 최상단으로 끌어올려 output1()을 먼저 호출하더라도 정상적으로 동작한다.

🥠 함수 표현식

output1(); // Uncaught TypeError: output1 is not a function
var output1 = function() {
	console.log('jung min');
}


// 호이스팅으로 변환된 코드
var output1;

output1(); // Uncaught TypeError: output1 is not a function

output1 = function() {
	console.log('jung min');
}

표현식의 경우 var output1;은 변수이기 때문에 선언과 할당의 분리가 발생한다.
output1 변수가 선언되고 output1();이 실행되고 그 이후에 output1에 함수가 정의되기 때문에 함수가 아니라는 오류메시지가 출력되는 것이다.

🥠 변수와 함수의 호이스팅 우선순위

var pyo = 'jung min';

function pyo() {
	console.log('pyo');
}

function jung() {
	console.log('jung');
}

console.log(typeof pyo); // output : string
console.log(typeof jung); // output : function


// 호이스팅으로 변환된 코드
var pyo;

function pyo() {
	console.log('pyo');
}

function jung() {
	console.log('jung');
}

pyo = 'jung min';

console.log(typeof pyo); // output : string
console.log(typeof jung); // output : function

위와 같이 호스팅 발생 시 함수 및 변수를 최상단으로 끌어올리고 그 이후에 할당되는 것을 확인할 수 있다.

javascript 작성시에 스코프(scope)와 호이스팅(hoisting)의 관계를 잘 생각하여 작성 하도록 하자.

0개의 댓글