(3장) 타입, 값, 변수 - 8. 스코프(Scope) 9. 호이스팅(Hoistng) [자바스크립트 완벽 가이드 7판]

iberis2·2022년 12월 31일
0

8. 스코프(scope)

스코프(scope)란 식별자 접근 규칙에 따른 유효 범위이다.

변수 접근 규칙에 따른 유효 범위

  • 안쪽 → 바깥쪽 스코프로는 접근할 수 있지만 반대(바깥 ⇏ 안)는 불가능
  • 스코프는 중첩이 가능
  • 전역 스코프(Global Scope)란 가장 바깥 스코프 ⇔ 지역 스코프(Local Scope)
    • 전역 변수 : 전역 스코프에서 선언한 변수
    • 지역 변수 : 지역 스코프에서 선언한 변수
  • 지역 변수는 전역 변수보다 더 높은 우선순위를 가짐
키워드constletvar
유효 범위블록 스코프
함수 스코프
블록 스코프
함수 스코프
함수 스코프
재할당⭕️⭕️
중복선언⭕️

Block Scope (블록 스코프)

{ } 중괄호로 감싸진 부분(코드 블록)을 기준으로 scope를 가짐

  • letconst 키워드로 선언한 변수는 if, for, function 등 어떤 키워드와 관계없이 코드 블록, 즉 { } 중괄호로 감싸진 부분을 기준으로 scope를 갖게 된다.
    • let const 는 Block Scope와 Function Scope 둘 다 해당
{let x = 1}
{const A = 2}

function myFunction() {let y = 3; const B = 4}

console.log(x); // ReferenceError: x is not defined
console.log(A); // ReferenceError: A is not defined
console.log(y); // ReferenceError: y is not defined
console.log(B); // ReferenceError: B is not defined

Function Scope (함수 스코프)

함수를 기준으로 scope를 가짐
즉, 함수 안에서 선언되었을 때만 지역 변수로써 지역 스코프를 가진다.

  • var 키워드로 선언한 변수는 scope가 function(함수)에서만 구분되어 있다.
  • var 변수는 if, for, while, switch 등 다양한 상황에서 선언한 변수가 전역변수의 역할을 하게 될 수도 있어 주의해야한다.
    💡 단, var 변수는 화살표 함수의 블록 스코프는 무시하지 않는다.
for(var i=0; i<10; i++) {
  console.log(i);
}

console.log(i); // 0 1 2 3 4 5 6 7 8 9 10
// var 키워드로 선언한 변수 i 는 지역 스코프에서 선언되었지만 모든 스코프에서 접근 가능하다.

function myFunction() {
  var y = 4;
}

console.log(y); // ReferenceError: y is not defined

let으로 선언한 변수를 같은 스코프에서는 재선언할 수 없지만, 다른 스코프에서는 동일한 이름의 변수로 다시 선언이 가능하다.
하지만 사실상 안쪽 스코프에서 새로 선안한 변수는 바깥쪽 스코프의 변수와 서로 다른 변수가 되는 것이므로 바깥쪽 스코프 변수에 영향을 끼칠 수 없다.

let student = '박코딩';  // 전역변수

function shwoName (){
	let student = '김자바'; // 지역 변수'student'를 새로 선언
    console.log(student);
}

console.log(student); // '박코딩'
showName(); 		  // '김자바'
console.log(student); //'박코딩'  (함수 안에서 선언한 변수는 바깥 스코프의 변수에 영향을 끼치지 않음)

반면 안쪽 스코프에서 바깥쪽 스코프의 변수를 그대로 사용하여 재할당 하는 경우 바깥쪽 스코프의 해당 변수의 값에 영향을 끼칠 수 있다.

let student = '박코딩';

function shwoName (){ 		
	student = '김자바';    // 전역변수 'student'를 그대로 사용하여 재할당
    console.log(student);
}

console.log(student);  //'박코딩'
showName(); 		   //'김자바'
console.log(student);  // '김자바'

window 객체


window 객체란 브러우저 창을 대표하는 객체이다.
브라우저 창과 관계없이 전역 항목도 담고 있다.
var로 선언된 전역 변수(전역 함수)가 window 객체에 속한다.
선언 키워드(var, let, const) 없이 변수 할당하는 경우 var로 선언한 전역변수처럼 취급된다.

💡var 보다는 let, const를 주로 사용할 것

  • var로 선언한 전역변수가 window 기능을 덮어씌워 내장 기능을 사용할 수 없게 만들 수도 있다.
  • 블록 스코프를 무시한다.
  • 재선언을 해도 에러가 나지 않는다.
  • side effect 발생 : 여러 사람이 코드를 작성하며 같은 이름으로 전역 변수를 선언하는 경우 의도하지 않은 변경, 문제 등이 발생할 수 있다.

9. 호이스팅(Hoisting)

호이스팅이란 ? 끌어올림, 즉 변수(상수)가 선언되기 이전에 접근 가능도록 끌어올려지는 현상

let 과 const

let, const 로 선언한 변수(상수)를 선언 이전에 사용할 수 없고, Error가 발생한다.

💡 하지만, ReferenceError: 변수(상수) is not defined 가 아닌 Uncaught ReferenceError: Cannot access '변수(상수)' before initialization 로 선언 이전에 접근할 수 없다는 Error가 나타난다.

console.log(myVariable); // Uncaught ReferenceError: Cannot access 'myVariable' before initialization
let myVariable; 

var

var 변수는 함수 스코프를 기준으로 선언되기 이전에도 변수에 접근이 가능하다.
단, 선언과 동시에 값을 할당하더라도, 선언문만 올려지기 때문에 값은 그대로 두 번째 줄에 남아있다.

console.log(myVariable); // undefined
var myVariable = 3;
console.log(myVariable); // 3

함수를 선언할 때에도 이 호이스팅(hoisting)이 적용된다.

sayHi(); // hi

function sayHi() {
  console.log('hi');
}

함수를 중간에 두고 선언되었을 경우에도 호이스팅이 적용된다.

console.log(sayHello); //undefined

function sayBye(){
  console.log('bye');
}

var sayHello = 'Hello'

함수 스코프 안에서 선언되었을 때에는 확실하게 Error가 나타난다

console.log(sayHello); //ReferenceError: sayHello is not defined

function greeting() {
  var sayHello = "Hello";
}
profile
React, Next.js, TypeScript 로 개발 중인 프론트엔드 개발자

0개의 댓글