jh.nrtv

JS 스코프(scope) - [Codestates] Section1 본문

javascript

JS 스코프(scope) - [Codestates] Section1

wlgus3 2022. 11. 7. 23:56

JavaScript에서 이야기하는 스코프 역시 무언가 제한된 범위를 잘 들여다보기 위해 사용되는 개념이라고 추측해 볼 수 있습니다.

컴퓨터 공학, 그리고 JavaScript에서의 스코프"변수의 유효범위"로 사용됩니다. 이번 챕터에서는 스코프(Scope)의 종류와 각 선언 키워드 (let, const)를 어떻게 사용해야 하는지 알아봅시다.

 

 

스코프와 주요 규칙

 

이처럼 변수에 접근할 수 있는 범위가 존재합니다. 중괄호(블록) 안쪽에 변수가 선언되었는가, 바깥쪽에 변수가 선언되었는가가 중요합니다. 이 범위를 우리는 스코프라고 부릅니다.

스코프 안쪽 -> 바깥쪽 변수에 접근 가능하지만 

스코프 바깥쪽 -> 안쪽의 변수에 접근 불가 

 

지역변수는 전역변수보다 더 높은 우선순위를 가진다. 

1. 지역스코프 안에 새로운 let

let name = '김코딩';

function showName() {
  let name = '박해커'; // 지역 변수
  console.log(name); // 두 번째 출력
}

console.log(name); // 첫 번째 출력
showName();
console.log(name); // 세 번째 출력

  -> 첫 번째 출력은 첫째 줄에서 전역 변수로 선언된 name을 가져옵니다. 이는, showName 함수 안쪽에 선언된 지역 변수 name은 애초에 스코프 규칙에 의해 접근할 수 없기 때문입니다. 따라서 "김코딩"을 출력합니다.

반면, 두 번째 출력은 함수 안에서 선언한 name이라는 지역 변수에 접근하고 있습니다. 변수 이름이 전역 변수와 똑같지만, 지역 변수가 전역 변수보다 우선순위가 높으므로, 지역 변수 name이 출력되는 것입니다. 동일한 변수 이름으로 인해 바깥쪽 변수가 안쪽 변수에 의해 가려지는(shadow) 이러한 현상 쉐도잉(variable shadowing)이라고 부릅니다.

두 번째 출력은 "박해커"입니다.

세 번째 출력은 첫 번째 출력과 마찬가지로 전역 변수 name을 출력합니다. 지역 변수에 선언된 name 변수는 안쪽 스코프이므로 접근이 불가능합니다. 따라서 "김코딩"을 출력합니다.

 

2. 지역스코프 안에 let 없음 -> 전역변수 그대로 가져다가 씀 

let name = '김코딩';

function showName() {
  name = '박해커';
  console.log(name); // 두 번째 출력
}

console.log(name); // 첫 번째 출력
showName();
console.log(name); // 세 번째 출력

  -> 앞서 문제와는 다르게, 세 번째 줄에서 let 키워드를 사용한 선언이 존재하지 않습니다.

이는, '박해커'라는 값으로 할당하고 있는 name 변수는 전역에 선언된 name 변수를 그대로 사용하겠다는 의미입니다.

지역 스코프에서 새로 선언되지 않으면 그냥 같은 변수입니다.

따라서 showName 함수가 실행되기 전, 처음에는 '김코딩'을 출력하고, 그 이후에는 전역변수 name의 값이 바뀌기 때문에 두 번째 및 세 번째 출력에 '박해커'가 출력됩니다.

 

 

 


변수 선언과 스코프 - 스코프의 종류와  let, const, var 키워드

 

블록 스코프 - 먼저 스코프는 두 가지 종류가 있습니다. 하나는 블록 스코프(block scope)라고 부르며, 중괄호를 기준으로 범위가 구분됩니다.

 

함수 스코프 - 또 다른 스코프 종류로는 함수 스코프(function scope)가 있습니다. function 키워드가 등장하는 함수 선언식 및 함수 표현식은 함수 스코프를 만듭니다.

 

화살표 함수 - 여기서 한 가지 유의해야 할 점이 있습니다. 화살표 함수 블록 스코프로 취급됩니다. 함수 스코프가 아닙니다. 함수 스코프와 블록 스코프는 논리적인 구분 외에도 코드를 작성할 때 기억해야 할 다른 점이 몇 가지 존재합니다. 지금은 그냥 이 둘은 차이가 있다는 정도로만 기억해도 좋습니다.

 

 

let 과 var 의 차이 

  -> var 은 for 문이 만든 블록스코프 무시

 

 

  -> 보통 코드를 작성할 때 블록은 들여쓰기가 적용되고, 그 구분이 시각적으로 분명합니다. 따라서 많은 사람들은 블록 스코프를 기준으로 코드를 작성하고, 생각하기 마련입니다. 그러나 var는 이 규칙을 무시하므로, 코드를 작성하는 사람이 블록 스코프/함수 스코프에 대한 이해가 없으면 코드가 다소 혼란스러울 수 있습니다. 따라서, var 보다는 let 으로 변수 선언을 하는 것을 권장합니다.

 

 

 

const키워드

const는 값의 재할당이 불가능합니다. 값을 재할당할 경우 TypeError를 내므로, 의도하지 않은 값의 변경을 막을 수 있습니다.

 

 

 

 

 


변수 선언할 때 주의할 점

 

먼저 브라우저에만 존재하는 window 객체에 대해 알아봅시다. 지금 개발자 도구를 열어 콘솔에 window 라고 입력해 보세요. 객체 하나를 조회할 수 있습니다. 이 객체는 사실 브라우저의 창(window)을 의미하는 객체이지만, 이와 별개로 전역 영역을 담고 있기도 합니다. 함수 선언식으로 함수를 선언하거나, var로 전역 변수를 만들면, window 객체에서도 동일한 값을 찾을 수가 있습니다.

 

   ->보통 애플리케이션을 만들 때에는, 내가 직접 작성하지 않은 수많은 다른 함수와 로직이 포함됩니다. 너도나도 똑같은 이름으로 전역 변수를 선언하려고 한다면 분명 문제가 발생할 것입니다. 이를 side effect라고 합니다. 전역 변수를 최소화하는 것은 side effect를 줄이는 좋은 방법입니다.

 

 

선언 없는 변수 할당 금지 ( strict mode ) 

 

  -> 사실 이런 것은 애초에 브라우저에서 방지해 준다면 더 안전하게 코드를 작성할 수 있을 것입니다. Strict Mode는 브라우저가 보다 엄격하게 작동하도록 만들어줍니다. 앞서 언급한 것처럼 "선언 없는 변수 할당"의 경우도 Strict Mode는 에러로 판단합니다. Strict Mode를 적용하려면, js 파일 상단에 'use strict' 라고 입력하면 됩니다. (따옴표 포함)

 

 

 


+ 추가

객체 (object), 속성 (property), 키 (key), 값 (value) 명확하게 구분하자. 

 

https://daramji-joa.tistory.com/21

 

[JavaScript] 객체(Object) // 속성(Property) // key값 ?

출처 객체(Object) 객체란, 현실의 사물을 프로그래밍에 반영한 겁니다. 코드로 보는게 이해하기 쉽겠죠? 저를 프로그래밍에 반영해서 간단한 코드로 만들어보겠습니다! 1 2 3 4 var zero = { firstName: 'Z

daramji-joa.tistory.com

 

 

함수는 태어난 곳이 중요하다 - 렉시컬 스코프 

https://ljtaek2.tistory.com/145