본문 바로가기

Front End

[JavaScript] Block Scope

반응형

함수 스코프: 함수에 의해서 생기는 변수의 유효 범위

블락 스코프: 블락에 의해서 생기는 변수의 유효 범위

 

변수 선언

  • val 함수 스코프를 따름
  • let 블락 스코프를 따름
  • const 블락 스코프를 따름

 

블락 스코프

Hoisting

  • var의 hoisting

-> 변수 a 생성

-> undefined 할당

 

  • let, const의 hoisting

 

 

-> 변수 a 생성

 

TDZ에 걸리므로 이전 reference error...

const 키워드로 hoisting..! a 의 존재는 알고 있으나, 값은 할당되지 않은 상태.. => reference error

 

*TDZ 임시 사각 지대

 

let

 

  • 블락 스코프 안에서만 유효
  • 중복 선언 불가능
  • 재 할당 가능
  • 호이스팅은 되나,
  • 일시적 사각지대가 존재 (not defined 에러)

funcs 배열에 함수를 넣어줌

각 배열의 요소 (함수 f)를 forEach문으로 각각 실행하면, 그 결과는 모두 10이 나온다.

포문은 모두 돌지만, 함수의 실행은 실제 그 함수가 호출될 때(forEach 문이 돌 때...) 된다.

 

함수가 실행할 때 실행 context가 열림

그 때, 변수를 생성, hoisting, this binding, 해당 스코프에 존재하지 않는 변수 외부에서 탐색 등 ... 

 

이 때문에, log를 찍는 함수의 실행 시점은 for문이 모두 종료된 뒤이다.

즉, 변수 i에는 10이 할당되어 있음

 

그렇다면, 어쩧게 0-9까지의 i를 찍을 수 있을 까?

i를 살려두라!

함수를 즉시 실행 함수로 바꾸자!

이 때, i를 미리 넘겨 주면, 즉시 실행 함수에서는 해당 i값을 가지고 있다

그 후에, 함수가 실행 될 때, console을 찍기위해 클로저로 리턴..

 

하지만, 

var가 아닌 let은 즉시 실행 함수 등 신경쓰지 않아도 된다.

let은 블락 스코프가 생성되기 때문에!!!

클로져안에서 선언된 변수는 영원히 산다.

 

const

const variable 

상수 변수

 

  • 블락 스코프 안에서만 유효
  • 중복 선언 불가능
  • 재 할당 불가능
  • 호이스팅은 되나,
  • 일시적 사각지대가 존재 (not defined 에러)
  • 선언만 할 수 없다.
  • 선언과 동시에 할당해야
  • 속성 값은 변경이 가능....(?)

참조 타입 데이터의 경우

 

const 객체의 속성값의 변경은 가능하지만, const로 선언한 객체 자체의 변경은 불가능 하다.

객체 안의 프로파티는 별도의 메모리에 저장되어 있어서 재 할당 가능.

배열의 경우도 마찬가지!

array 객체 자체는 immutable이지만, push도 delete도 가능

 

내부의 파라미터까지 immutable로 만들기

1. defineProperty

2. freeze

그러나, 참조형 property의 경우?

freeze한 객체의 property의 property는 역시 mutable

 

얕은 복사

객체가 할당된 메모리 주소를 복사

a와 b는 같은 메모리를 가리키고 있기 때문에

a.b까지 바뀜

 

깊은 복사

객체의 속성 변수의 값을 복사

다른 메모리를 가리키고 있음.

a와 b는 다른 메모리를 가리키고 있기 때문에, b의 속성값을 변경하여도 변경되지 않음..

 

완전한 immuatable한 객체를 만들기 위해서는 객체의 모든 참조형인 속성을 체크하야 깊은 복사를 해야 함.

 

for문 안에서의 const 선언?

 

가능!

for문의 블락 스코프 안에서만 prop이 유효하기 때문에

다음 루프 시에 초기화 가능

 

그러나,,,,

const인 i의 값을 for 문의 조건절 내에서 초기화하는 것은 불가능

 

전역변수(var)의 선언을 최소화 하라.. 하지마라!!

var a = 10
console.log(window.a)
console.log(a)
delete a
console.log(window.a)
console.log(a)

window.b = 20
console.log(window.b)
console.log(b)
delete b
console.log(window.b)
console.log(b)

let c = 30
console.log(window.c)
console.log(c)
delete c
console.log(window.c)
console.log(c)

const d = 40
console.log(window.d)
console.log(d)
delete d
console.log(window.d)
console.log(d)

 

 

반응형

'Front End' 카테고리의 다른 글

[JavaScript] enhanced object  (0) 2019.10.27
[JavaScript] template tag function  (0) 2019.10.21
[JavaScript] forEach, map, reduce  (0) 2019.10.20
Template literal  (0) 2019.10.19
[JavaScript] this  (0) 2019.10.12