JavaScript

JavaScript 스코프(scope)

이히힣 2022. 7. 21. 03:52

[스코프(scope)]

 

  • 범위는 중괄호(블록) 또는 함수에 의해 나누어지는데 그 범위를 스코프라 한다.
  • 바깥쪽 스코프에서 선언한 변수는 안쪽 스코프에서 사용 가능하다.
  • 안쪽 스코프에서 선언한 변수는 바깥쪽 스코프에서는 사용할 수 없다.(ReferenceError)

 

 

 

예시1)

 

let greeting = 'Hello';

function greetSomeone() {                     // 스
  let firstName = 'A';                        // 코
  return greeting + ' ' + firstName;          // 프
}

console.log(greetSomeone()); // Hello Josh 
// greeting 변수는 바깥 스코프에 정의되어 있으므로, 함수 안쪽에서 사용할 수 있음.

console.log(firstName); // ReferenceError 
// firstName 변수는 안쪽 스코프에 정의되어 있으므로, 함수 바깥쪽에서 사용할 수 없음.

 

 

 

예시2)

 

let name = 'Alex';

function showName() {
  let name = 'James'; // 지역 스코프
  console.log(name); 
}

console.log(name); // Alex 
// showName 함수 안쪽에 선언된 지역 스코프는 스코프 규칙에 의해 전역 스코프에 접근 불가능.
showName();        // James 
// 지역 스코프가 전역 스코프보다 우선순위가 높음.
console.log(name); // Alex
// showName 함수 안쪽에 선언된 지역 스코프는 스코프 규칙에 의해 전역 스코프에 접근 불가능.

 

 

 

예시3)

 
let name = 'Alex';

function showName() {
  name = 'James';        // let을 사용한 선언이 존재하지 않음.
  console.log(name);     // 지역 스코프에서는 'James'는 값을 할당하고, 전역 스코프에 선언된 name 변수를 그대로 사용
}

console.log(name); // Alex   전역 변수에서 사용한 값 그대로 사용
showName();        // James  지역 스코프에서 새로 선언되지 않으면 그냥 같은 변수
console.log(name); // James

 

동일한 변수 이름으로 인해 바깥쪽 변수가 안쪽 변수에 의해 가려지는(shadow) 이러한 현상을 쉐도잉(variable shadowing)이라 한다.

 

 

 

 

 

[스코프의 종류]

 

블록 스코프(block scope)

 

중괄호를 기준으로 범위가 구분한다.

화살표 함수는 블록 스코프이다.

 

 

 

함수 스코프(function scope)

 

함수 선언식 및 함수 표현식은 함수 스코프이다.

화살표 함수는 블록 스코프이다.

 

 

 

 

 

[ 변수를 정의하는 방법: let / const / var 비교]

 

[let]

 

변수를 정의하는 가장 대표적인 방법이다.

블록 스코프의 범위를 가지는 지역 변수를 선언한다.

선언과 동시에 임의의 값으로 초기화할 수도 있다.

var 보다는 let 으로 변수 선언을 하는 것을 권장한다.(var의 한계점을 보완하기 위해 만들어졌다.)

 

 

 

[var] 

 

var 키워드로 정의한 변수는 블록 스코프를 무시하고, 함수 스코프만 따른다.

단, 화살표 함수의 블록 스코프는 무시하지 않는다.

 

 

 

공통점:

 

자신을 선언한 블록과 모든 하위 블록을 스스로의 스코프로 가진다. 

 

차이점:

 

let은 자신을 선언한 블록'을 뜻하지만

var의 경우 스코프가 '자신을 선언한 블록'이 아니라, 자신의 선언을 포함하는 함수를 뜻한다.

 

 

 

var 보다는 let 으로 변수 선언을 하는 것을 권장하는데 var 키워드보다 let 키워드가 안전한 이유는 let 키워드가 재선언을 방지하기 때문이다. 실제로 코딩할 때에 변수를 재선언해야 할 필요가 없다.( 대부분 이런 경우는 버그)

 

 

 

 

 

[const]

 

값이 변하지 않는 상수(constant)를 정의한다.

const는 값의 재할당이 불가능하다. (값을 재할당할 경우 TypeError)

값을 새롭게 할당할 일이 없다면 const 키워드 사용 권장한다.

 

 

 

  let const var
유효 범위 블록 스코프 및 함수 스코프 블록스코프 및 함수 스코프 함수 스코프
값 재할당 가능 불가능 가능
재선언 불가능 불가능 가능

 

 

 

 

 

[변수 선언에서 주의할 점]

 

1. var로 선언된 전역 변수 및 전역 함수는 window객체에 속한다.(브라우저에만 존재) - 전역변수

브라우저에는 window라는 객체가 존재한다.

브라우저 창을 대표하는 객체지만 브라우저 창과 관계없이 전역 영역 항목도 담고 있다.

함수 선언식으로 함수를 선언하거나, var로 전역 변수를 만들면, window 객체에서도 동일한 값을 찾을 수가 있다.

 

 

2. var로 선언된 전역 변수와 전역함수가 window 객체에 속한다.

var 키워드는 블록 스코프를 무시한다.(화살표 함수 제외) 또한 재선언을 해도 에러를 내지 않는다. 따라서, let과 const를 주로 사용한다.

 

 

 

 

 


   ⭐️⭐️⭐️중요⭐️⭐️⭐️

 

  •  안쪽 스코프에서 바깥쪽 스코프로는 접근할 수 있지만 반대는 불가능하다
  •  스코프는 중첩이 가능하다
  •  가장 바깥쪽의 스코프는 전역 스코프(Global Scope), 전역스코프를 제외한 다른 스코프는 전부 지역 스코프(local scope)다.
  •  지역 스코프는 전역 스코프보다 더 높은 우선순위를 가진다.
  •  var로 선언한 변수는 window 객체에 속하게 된다.
  • 선언 없는 변수 할당 금지 ('use strict') 라고 입력한다.

strict mode를 사용하면 ‘선언 없는 변수 할당’을 브라우저가 에러로 처리하기 때문에 side effect를 방지할 수 있다.