[JS] 모던 자바스크립트 Deep Dive 스터디 13장~15장 스코프 #해달

2024. 2. 2. 13:28_Web/JavaScript

728x90

 

 

 

 

 

 

 

 

 

#전역변수 #스코프 #식별자 #스코프체인


 

 

 

Scope(유효범위) 식별자가 유효한 범위 , 식별자를 검색할 때 사용하는 규칙, 네임스페이스

 

 

-> 변수를 포함한 모든 식별자(함수 이름, 클래스 이름 등)는 자신이 선언된 위치에 의해 다른 코드가 식별자 자신을 참조할 수 있는 유효범위

 

식별자 결정: 같은 이름을 가진 변수중에서 어떤 변수를 참조할 것인가를 자바스크립트 엔진이 결정하는 것

 

코드의 문맥

 

"코드가 어디서 실행되며, 주변에 어떤 코드가 있는지"를 나타내는 렉시컬 환경으로 이루어짐.

모든 코드는 이를 구현한 실행컨텍스트에서 평가되고 실행함.

 

 

var, let, const의 중복선언

-> var은 같은 스코프 내의 중복 선언 허용

-> let, const 는 같은 스코프 내의 중복 선언 불가능 (SyntaxError)

 

함수스코프, 블록스코프, 호이스팅, 전역스코프

 

 

지역변수는 자신의 지역스코프와 하위 지역스코프에서 유효.

스코프 체인: 함수의 중첩: 함수 몸체 내부에서 함수가 정의된것

 

 

→ 변수 참조 시, 자바스크립트 엔진은 스코프 체인을 통해 참조하는 코드의 스코프에서 시작하여 상위 스코프 방향으로 이동하며 선언된 변수를 검색

→ 자바스크립트 엔진의 변수 검색은 단방향 (상위 스코프를 향하여)

→ 상위 스코프의 유효변수는 하위 스코프에서 참조 가능, 반대는 불가능.

 

 

전역 변수를 어디에서 많이 쓰나?

🎨 CSS 변수(--variable) 사용법 & 응용 정리 (tistory.com)

 

🎨 CSS 변수(--variable) 사용법 & 응용 정리

CSS 변수 기능 복잡한 웹사이트 같은 경우 엄청난 양의 CSS를 가지고 있는데, 유지보수를 하다 보면 여러 곳에서 사용한 임의의 값을 한꺼번에 바꿔야 할 때가 있다. 그 값들을 하나씩 찾아서 일일

inpa.tistory.com

필요없는 코드를 많이 줄이고, 재사용성을 극대화하려면 CSS에도 할 수 있다.

ex) scss $color-primary

색상템플릿에서 8개 정도 사용하면, 가져다가쓰기

 

 

 

 

함수 레벨 스코프

 

 

함수 레벨 스코프: 함수의 코드 블록만을 지역스코프로 인정하는 특성

블록 레벨 스코프: 함수뿐아닌 모든 코드 블록이 지역스코프를 만드는 특성

 

 

var x = 1;
if (true){
	var x = 10;
}
console.log(x); //10

 

→ var의 경우 블록을 스코프 범위로 인정하지 않아 같은 스코프로 인지하여 값을 재할당하고 변경하는 부작용.

 

 

 

<스코프 계층 결정 방식>

 

동적 스코프: 함수를 어디서 호출했는지에 따른 상위 스코프 결정

렉시컬 스코프(정적 스코프): 함수를 어디서 정의했는지에 따른 상위 스코프 결정→ 위의 예제의 bar 함수는 전역에서 정의되었으니 어디서 호출하든지 전역스코프를 상위 스코프로 사용.

자바스크립트는 렉시컬 스코프를 따름.

 

 

 

 

 

14. 전역 변수의 문제점

 

14.1 변수의 생명주기

 

변수의 생명주기: 변수가 선언에 의해 생성되고 할당을 통해 값을 가지고 소멸되는 주기

어플의 생명주기와 같은 전역 변수의 생명주기와 달리,→ 함수 내부 변수의 선언은 함수 호출 직후에 실행.

지역변수의 생명주기는 대부분 함수의 생명주기와 일치 (함수 호출 시 생성, 함수 종료 시 소멸)

 

 

어플의 생명주기와 같은 전역 변수의 생명주기와 달리,→ 함수 내부 변수의 선언은 함수 호출 직후에 실행.

지역변수의 생명주기는 대부분 함수의 생명주기와 일치 (함수 호출 시 생성, 함수 종료 시 소멸)

 

var x = 'global';

function foo(){
	console.log(x);
	var x = 'local';
}

foo();
console.log(x);

 

→ 지역 변수는 자신이 등록된 스코프가 소멸될 때까지 유효. 그 누구도 참조하지 않을 때 가비지 콜렉터에 의해 해제.

→ 즉, 호이스팅은 변수 선언이 스코프의 선두로 끌어 올려진 것처럼 동작하는 자바스크립트의 특징을 말함.

 

 

 

암묵적 결함 - 모든 코드가 전역 변수를 참조하고 변경할 수 있는 것.

⇒ 코드의 가독성 저하, 의도치 않은 상태 변경 위험성 증가

 

긴 생명 주기⇒ 변수 상태 변경의 기회와 시간이 많아진다.(오류발생 확률증가)

⇒ 메모리 리소스를 장시간 소비.

 

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

⇒ 전역 변수의 검색 속도가 가장 느림.

 

네임스페이스 오염

⇒ 파일이 분리되어도 하나의 전역 스코프를 공유하는 자바스크립트의 문제점이 있음. 다른 파일 내의 동일 이름인 전역 변수와 전역 함수가 존재할 수 있음.

 

 

 

 

네임스페이스 객체

⇒ 전역에 네임스페이스 역할을 담당할 객체를 생성하고 전역 변수처럼 사용하고 싶은 변수를 프로퍼티로 추가 (식별자 충돌 방지)

 

모듈 패턴: 클래스를 모방하여 관련이 있는 변수와 함수를 모아 즉시 실행 함수로 감싸 하나의 모듈을 만든다.

캡슐화: 객체의 상태를 나타내는 프로퍼티와 프로퍼티를 참조하고 조작할 수 있는 동작인 메서드를 하나로 묶는 것→ 자바스크립트는 public, private 등의 접근 제한자를 제공하지 않음.

→ 정보 은닉: 객체의 특정 프로퍼티나 메서드를 감출 목적으로 캡슐화를 하는 것.

⇒ 전역 네임스페이스 오염 방지, 정보은닉의 기능을 한다.

⇒ 전역 변수의 억제, 캡슐화 구현의 특징을 가짐.

 

 

 

클로저 : 클로저 기반으로 동작

모듈 : 프로그램을 구성하는 구성 요소로, 관련된 데이터와 함수를 하나로 묶은 단위

 

 

 

ES6 모듈→ 모듈 내에서 var 키워드로 선언한 변수는 전역 변수가 아님

→ script 태그에 type=”module” 어트리뷰트를 추가하면 로드된 자바스크립트 파일은 모듈로서 동작

⇒ 파일 자체의 독자적인 모듈 스코프를 제공함.

 

 

 

 

 

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

 

- 변수 중복 선언을 허용

var x = 1;
var y = 1;
var x = 100; 
var y; //초기화문 없으면 무시

 

 

함수 레벨 스코프

⇒ 이것은 전역 변수를 남발하고 중복 선언되는 가능성을 높인다.

⇒ 함수의 코드 블록만을 지역 스코프로 인정.

var i = 10;
for (var i = 0; i < 5; i++){
	console.log(i);
}
console.log(i); //5

 

 

 

변수 호이스팅

⇒ var 키워드의 변수 선언은 변수 호이스팅이 발생

console.log(foo);
foo = 123;
console.log(foo);
var foo;

⇒ 가독성 저하, 오류 발생 여지를 남김.

⇒ 선언 단계 + 초기화 단계가 묶여 동시 진행되는 var 키워드와 달리, let 키워드의 변수는 선언과 초기화 단계가 분리되어 진행

→ 런타임 이전에 자바스크립트 엔진에 의해 암묵적으로 선언단계 먼저 실행, 초기화 단계는 변수 선언문에 도달 시.

 

 

일시적 사각지대: 스코프의 시작 지점부터 초기화 시작 지점까지 변수를 참조할 수 없는 구간

console.log(foo); //ReferenceError
let foo;
console.log(foo); //undefined
foo = 1;
console.log(foo); //1

 

⇒ 하지만 호이스팅이 발생함.

let foo = 1;
{
	console.log(foo); //ReferenceError
	let foo = 2;
}

 

선언단계 초기화 단계 분리

 

 

전역 객체와 let⇒ But, let 키워드로 선언한 전역 변수는 전역 객체의 프로퍼티가 아님.⇒ var 키워드로 선언한 전역 변수, 전역 함수, 선언하지 않은 변수에 값을 할당한 암묵적 전역은 전역 객체 window의 프로퍼티가 됨. (전역 객체의 프로퍼티 참조 시 window 생략 가능)

 

let x = 1;

console.log(window.x); //window의 프로퍼티가 아니여서 undefined
console.log(x);

 

 

var / let / const 어떻게 사용해야할까?

변수의 스코프는 최대한 좁게

읽기전용으로 사용하는 원시값과 객체에는 const 키워드를 사용하기

 

const는 재할당을 금지하는데 useState()는?

 

재할당 : 메모리공간?

 

 

person :

프로퍼티 동적 변경을 통해 객체를 변경하는 것은 가능