본문 바로가기
Front-End/JavaScript

13. 스코프 14. 전역 변수의 문제점 15. let, const 키워드와 블록 레벨 스코프 (모던 자바스크립트 Deep Dive)

by kk님 2023. 4. 3.

모던 자바스크립트 Deep Dive글 목록(스터디)

https://hello-kk.tistory.com/780

13. 스코프

핵심이라고 생각되는 개념. 각 의미를 기억하자

스코프, 스코프 체인, 렉시컬 스코프 ( vs 렉시컬 환경)

 

var에 대한 (나의) 오해와 진실

전역 스코프에 선언된 var x= 10;
함수 스코프에 선언된 var x =20;
함수 내부에선 당연히 20이지만,
함수가 종료되면?

var x = 10;

function outer(){
	var x = 20;
    console.log(x) // (1)
}
console.log(x) // (2)


(처음엔) 20인줄 알았다. 재선언이 가능하고 다시 할당한 것과 같은 것으로 생각해서..

그래서 전역 스코프의 x가 수정된 것이라 생각했는데, 그게 아니라 단지 지역스코프 내에 x가 따로 있는 것.
(잘 이해하고 있던 것)
만약 함수 스코프 내에 x가 없다면 outer환경레퍼런스를 통해 전역 범위 렉시컬 환경을 참조했을 것
let이라면 그냥 함수 종료 후에는 전역에 선언한 변수라고 생각
var이라서.. 함수 종료후 바뀐다고 생각했는데 왜지?=> 블록스코프라면 다르다. 블록스코프면 바뀜 그래서 let과 헷갈림

 

스코프: 식별자가 유효한 범위

=> 자신이 선언된 위치에 의해 다른 코드 식별자 자신을 참조할 수 있는 유효범위가 결정되는 것

또는

=> 자바스크립트 엔진이 식별자를 검색할 때 사용하는 규칙

식별자 결정: 

 

  중복 선언이 가능한가? 재할당이 가능한가?    

 

스코프 체인: 스코프가 계층적으로 연결된 것

- 스코프가 함수의 중첩에 의해 계층적 구조를 갖는다.

 

*함수의 렉시컬 환경은 함수가 호출되면 곧바로 생성

var: 함수 레벨 스코프 ↔ 블록 레벨 스코프

 

*렉시컬 스코프

함수를 어디서 정의했는지에 따라 함수의 상위 스코프를 결정

 

14. 전역 변수의 문제점

(내가 몰랐던) 변수 선언의 진실 ...

자바스크립트 엔진에 의해 선언문은 어디에 있든, 가장 먼저 실행된다 ???

=> 이 설명은 전역 변수에 한정한다.

=> 지역 변수는! 함수가 호출되기 전까지는 생성되지 않다가, 함수를 호출한 이후에야 자바스크립트 엔진에 의해 생성된다.(실행 컨텍스트와 연관, 런타임 이전.)

1. 선언: 자바스크립트 엔진에 의해 생성, (런타임 이전), undefined 로 초기화

2. 할당: 코드(할당문) 실행(런타임)시

 

지역변수가 함수보다 오래 생존하는 경우

: 자신의 스코프가 참조되고 있는 경우

 

전역 변수는 전역 객체(window)의 프로퍼티

 

전역 변수의 문제점

1. 암묵적 결합: 모든 코드가 전역 변수 참조 및 수정 가능

=> 암묵적 결합에의해 유효 범위가 클수록 가독성이 나빠지고 의도치 않은 상태 변경에 노출될 위험이 있다

2. 긴 생명 주기

=> 의도치 않은 재할당(, 메모리 리소스)

3. 스코프 체인 상에서 종점에 존재

=> 느린 검색 속도

4. 네임 스페이스 오염

 

전역 변수의 사용을 억제하는 방법

1. 즉시 실행 함수

2. 네임스페이스 객체

객체 생성, 프로퍼티로 추가

=> 그러나, 객체가 전역 변수에 할당되므로..

3. 모듈 패턴: 클로저 기반

★생성 예제 작성해보기

할당되는 변수객체의 프로퍼티는 public 멤버 ↔ private 멤버

 

15. let, const 키워드와 블록 레벨 스코프

var y =1;
var y;
console.log(y) //

=> 한번 할당된 변수의 경우, 초기화문이 없는 변수 선언을 하게 되면 undefined가 아니라, 무시된다.

 

변수 호이스팅: 선언문이 스코프의 최상단으로 끌어올려진 것처럼 동작하는 것을 의미한다.

 

  중복 선언이 가능한가? 재할당이 가능한가? 함수 레벨 스코프?
블록 레벨 스코프?
변수 호이스팅 차이 전역 객체와의 관계
var       1. 선언단계+초기화 단계 전역 객체의 프로퍼티
let       1. 선언단계
2. 초기화 단계
X

let 의 초기화 시점?

1. 호이스팅으로 선언부가 끌어올려진다.

2. 실제로 선언한 줄(선언문)에서 초기화가 실행된다.

3. 할당

=> 즉, 선언문 이전에 변수에 접근한다면 참조 에러가 발생한다.

 

*암묵적 전역?(24장 참고)

 

const 변수에 객체를 할당한 경우, 객체 내 값 변경 가능. =>하지만 변수에 할당된 참조값은 변하지 않는다.

즉, 재할당을 금지할 뿐, 불변하지는 않다.

 

일단 const로 선언한 뒤, let 키워드로 변경하도록 하자. => 선언 시점에서는 변경될지 모를 수 있기 때문에.