이롭게 현명하게
[JavaScript] 자바스크립트 Scope와 hoisting 본문
목차
scope 이해하기
hoisting
var의 호이스팅
let의 호이스팅
호이스팅을 피해야 하는 이유
https://devyihyun.tistory.com/124
[scope 이해하기]
scope : 변수, 함수를 선언할 때 해당 변수 또는 함수가 사용할 수 있는 범위를 의미한다.
<scope 종류>
- Global : 코드의 전 범위에서 사용할 수 있다.
- Function : 특정 함수 내부에서만 사용할 수 있다.
- Block : if, for, while, switch 등과 같은 것을 작성할 때 사용하는 중괄호 범위(block) 내에서 사용가능
index.js
const value = "hello!"; // Global Scope
function myFunction() {
console.log("myFunction : ");
console.log(value);
}
function otherFunction() {
console.log("otherFunction : ");
const value = "bye!"; // Function Scope
console.log(value);
}
myFunction();
otherFunction();
console.log("global scope : ");
console.log(value);
const value = "hello!'; 는 Global scope이다.
myFunction의 value의 값은 "hello!"이다.
otherFunction 함수 내부에 const value = "bye!"; 변수를 선언해 주었다.
이때 value는 함수 내부에서만 유효한 값이 된다.
그래서 console.log()에는 "bye!'가 출력된다.
이때 Global scope인 const value="hello!"; 에는 아무런 영향을 주지 않는다.
const value = "hello!'; 는 Global scope이다.
if문 내부에 있는 const value="world";는 block scope이다.
그래서 if문 내부에서만 유효한 값이 된다.
이때 Global scope인 const value="hello!"; 와 Function scope인 const value = "bye!";에는 아무런 영향을 주지 않는다.
index.js
const value = "hello!"; //global scope
function myFunction() {
const value = "bye!"; //function scope
if (true) {
const value = "world"; // block scope
console.log("block scope : ");
console.log(value);
}
console.log("function scope : ");
console.log(value);
}
myFunction();
console.log("global scope : ");
console.log(value);
var은 함수 단위로만 존재한다.
[hoisting]
hoisting : 자바스크립트에서 아직 선언되지 않은 함수, 변수를 끌어올려 사용할 수 있는 자바스크립트의 작동방식이다.
변수 선언문이 코드의 선두로 끌어올려진 것처럼 동작하는 자바스크립트 고유의 특징이다.
자바스크립트 엔진은 코드를 실행하기 전 코드를 위에서부터 한 줄, 한 줄 살펴보면서 소스 평가 과정을 거친 후에 소스코드를 실행한다.
하지만 자바스크립트에서는 밑에 있는 것을 끌어올려 사용한다.
이것을 호이스팅이라고 한다.
[var의 호이스팅]
자바스크립트에서 아래의 코드를 실행하면 자바스크립트 엔진은 맨 앞에 있는 console.log부터 시작하여 하나하나씩 내려가면서 변수 선언문 또는 함수 선언문 등을 찾아내어 먼저 실행한다.
console.log(apple); // undefined
var apple;
apple="사과"
console.log(apple); // 사과
자바스크립트 엔진은 처음에 var apple;을 찾는다.
자바스크립트 엔진은 해당 변수를 맨 위로 끌어올려 맨 위에 첫 줄에 있는 console.log보다 앞서서 실행하게 된다.
이렇게 소스 평가 과정을 모두 거친 후 자바스크립트는 소스코드를 실행하게 된다.
console.log(a); // 오류가 예상된다. 하지만 호이스팅에 의해 선언 및 초기화 undefined
a=123;
console.log(a);
var a; // 변수 선언
첫 줄에서 변수 a를 출력한다.
호이스팅을 전혀 고려하지 않는다면 a가 선언되지 않았으니 오류가 생길 것이라 예상된다.
하지만 바로 밑에 변수 a가 선언되어 있다.
자바스크립트에서는 이미 호이스팅에 의해 a가 선언되고 undefined로 초기화된 상태이다.
콘솔에는 undefined가 출력된다.
a에 123을 할당하였다.
콘솔에 123이 출력된다.
이 코드를 실행순서로 변경하면 다음과 같다.
var a;
console.log(a);
a=123;
console.log(a);
코드를 재배치하니 이전보다 이해하기 쉬워진다.
이런 호이스팅의 특성은 가독성을 해치고 오류를 발생시킬 가능성이 높다.
[let의 호이스팅]
var의 경우 호이스팅이 이루어져 맨 앞으로 끌어올려지기 때문에 아직 변수가 선언되기 전인데도 콘솔로 apple값을 출력하면 에러가 나지 않고 undefined가 나타난다.
console.log(apple);
var apple;
하지만 let의 경우는 다르다.
console.log(apple);
let apple;
console.log(apple);
apple="사과"
console.log(apple)
let은 호이스팅이 발생하지 않는 것처럼 동작한다.
그래서 var와 달리 undefined가 아닌 참조에러(ReferenceError)가 발생하면서 코드가 동작하지 않는다.
값을 할당하지 않고 선언만 했을 때에 undefined를 출력한다.
제대로 출력되려면 변수를 선언하고 값에 할당까지 이루어진 다음에 이루어진다.
https://devyihyun.tistory.com/206
<호이스팅을 피해야 하는 이유>
- 코드를 이해하가 힘들어진다.
- 유지보수가 힘들어진다.
- 오류를 발생시킬 가능성이 높다.
let과 const로 선언한 변수고 hoisting 대상이지만, var와 달리 hoisting 시 undefined로 변수를 초기화하지는 않는다.
변수 생성 과정이 달라 사각지대가 생성되어 초기화 전에 액세스 할 수 없다는 레퍼런스 에러를 발생한다.
잘못된 정보는 댓글에 남겨주시면 감사하겠습니다!😊
'댓글'과 '좋아요'는 큰 힘이 됩니다!
'웹 개발 > JavaScript' 카테고리의 다른 글
[JavaScript] 자바스크립트 시작하기 (1) | 2023.11.24 |
---|---|
[JavaScript] 배열 내장 함수 (0) | 2023.11.21 |
[JavaScript] 자바스크립트 spread와 rest (0) | 2023.05.17 |
[JavaScript] 자바스크립트 프로토타입과 클래스 (0) | 2023.05.16 |
[JavaScript] 자바스크립트 객체 (0) | 2023.05.15 |