Unit.9 스코프

2023. 1. 2. 15:24코드스테이츠/코드스테이츠S1: Chapter & Unit

스코프(scope)

함수가 실행될때, 함수 내에서 변수에 대한 접근이 어떻게 되든지를 나타내는 용어이다. (함수의 실행 컨텍스트 내에서의 변수 환경이 무엇인지) 스코프는 함수를 기반으로 한 용어이다.


컨텍스트(context)

this 키워드 값이 무엇인지를 나타내는 용어이다. 현재 실행 컨텍스트 내에서 어떤 객체를 참조하고 있는지를 의마한다. 컨텍스트는 객체를 기반으로 한 용어이다.


 

함수스코프

  • 자바스크립트는 기본적으로 함수 스코프를 따르는 언어
  • 함수스코프를 따른다? => 새로운 함수가 생성될때마다 새로운 스코프가 발생한다.
    - 함수 몸체에 선언한 변수는 해당 함수 안에서만 접근할 수 있음
  • 함수스코프 -> 지역스코프
if(5 > 4) {
	var secret = '12345';
}
secret // '12345'
  • 위 코드에서는 함수가 선언되어 있지 않기 때문에 새로운 환경, 새로운 스코프가 형성되지 않는다.
  • 스코프가 형성되지 않으므로 동일한 실행 컨텍스트 내에서 존재하는 것이다.
  • 그렇기때문에 어디에서나 secret변수에 대한 접근이 가능하다.
function a() {
	var secret = '12345';
}
secret; //ReferenceError
  • 반면 이 경우는 함수 생성과 동시에 a함수에 대한 새로운 실행 컨텍스트가 생성되고,
  • 이 실행 컨텍스트 내부에 존재하는 변수환경(variable environment)에 secret변수가 저장된다.
  • 따라서 함수 외부에서 secret에 접근하려고 할 경우 스코프가 다르기 때문에 해당 변수에 접근이 불가능하다.
  • 함수외부는 global scope이고, 함수 내부는 a함수의 scope인데 부모스코프는 자식스코프에서 간섭할 수 없기 떄문에 접근이 불가능하다.

블록 스코프

  • 블록스코프는 말 그래도 블록 {}이 생성될 때마다 새로운 스코프가 형성되는 것을 의미
  • 원래 자바스크립트는 함수 스코프를 따르지만, let과 const 키워드의 등장으로 블록 스코프를 형성하는 것도 가능해졌다.
function loop() {
	for(var i = 0; i < 5; i++) {
		console.log(i);
	}
	console.log('final',i);
}
loop();
/*
	0
	1
	2
	3
	4
	final 5
*/
  • 이 코드를 보면, for문 안에서 변수 i를 var 키워드로 초기화 해줬다.
  • 이 경우에는 블록 스코프가 아닌 함수 스코프를 따르게 되는데, for문 안쪽과 바깥 쪽에서 모두 변수 i에 접근해서 console.log를 하고 있다.
  • 이 때는 어차피 loop이라는 함수 스코프 안에 둘 모두 존재하기 때문에 문제 없이 for문 안이든 밖이든 문제없이 i에 접근해서 값을 출력한다.
function  loop() { 
	for (let i = 0; i < 5; i++) { 
		console.log(i); 
	} 
	console.log('final', i); 
} 
loop(); /* ReferenceError: i is not de
  • 반면 for문 내에서 i를 let으로 선언할 경우에는 달라진다.
  • let으로 선언한 순간, 변수i는 for문 내에서만 종속되며, for문 외부에서는 i에 접근할 수가 없다.
  • 스코프가 다르기 때문이다.

변수 선언 시 주의할 점

 

전역 변수는 최소한으로

전역 변수는 가장 바깥 스코프에 정의한 변수입니다. 따라서, 어디서든 접근이 가능합니다. 얼핏 "모든 변수를 바깥으로 빼면 스코프 걱정을 하지 않아도 되겠네?" 라는 생각이 들 수도 있습니다. 그러나, 전역 변수를 많이 만드는 것은 그다지 좋은 선택이 아닙니다. 보통 애플리케이션을 만들 때에는, 내가 직접 작성하지 않은 수많은 다른 함수와 로직이 포함됩니다. 너도나도 똑같은 이름으로 전역 변수를 선언하려고 한다면 분명 문제가 발생할 것입니다. 이를 side effect라고 합니다. 전역 변수를 최소화하는 것은 side effect를 줄이는 좋은 방법입니다.


let , const 를 주로 사용하라

var는 블록 스코프를 무시하며, 재선언을 해도 에러를 내지않는다.

-같은 스코프에서 동일한 이름의 변수를 재선언 하는 것은 버그를 유발한다.

 

전역 변수를 var로 선언하는 경우 문제가 될 수 있다.

-var로 선언한 전역 변수가 window 기능을 덮어씌워서 내장 기능을 사용할 수 없게 만들 수 있다.


 

선언 없는 변수 할당 금지

 

선언 없이 변수를 할당하면, 해당 변수는 var로 선언한 전역 변수처럼 취급된다.


Strict Mode

Strict Mode는 브라우저가 보다 엄격하게 작동하도록 만들어 준다.

앞서 언급한 것처럼 "선언 없는 변수 할당"의 경우도 Strict Mode는 에러로 판단한다.

Strict Mode를 적용하려면, js 파일 상단에 'use strict' 라고 입력하면 된다. (따옴표 포함)

 

Strict Mode 선언하는 방법


요약

  1. 스코프란?
  • 변수에 접근할 수 있는 범위
  • 함수 실행컨텍스트 내부의 변수 환경
  1. 컨텍스트란?
  2. 함수스코프란?
  • 새로운 함수가 생성되면 새로운 스코프가 발생한다.
  • 자바스크립트는 함수스코프를 따르는 언어
  • 함수에서 선언한 변수들은 해당 함수 내에서만 접근할 수 있다.
  1. 블록스코프란?
  • 블록이 생성될때 새로운 스코프가 생성
  • 자바스크립트는 원래 함수스코프를 따르지만, let과 const의 등장이후로 블록스코프형성도 가능해짐
  1. var와 let,const를 함수스코프, 블록스코프??
  • var => 함수스코프
  • let, const => 블록스코프

'코드스테이츠 > 코드스테이츠S1: Chapter & Unit' 카테고리의 다른 글

Unit.10 DOM  (0) 2023.01.05
Unit.9 JS[spread/rest] 문법  (0) 2023.01.03
Unit.9 원시자료형과 참조자료형  (0) 2023.01.02
Unit.8 배열  (0) 2022.12.29
Unit4-[CSS] 셀렉터  (0) 2022.12.22