320x100
320x100

코드 블록

: { ... } 

: 이 안에서 선언한 변수는 블록 안에서만 사용할 수 있음

 

 

 

중첩 함수

: 함수 내부에서 선언한 함수

function sayHiBye(firstName, lastName) {

  // 헬퍼(helper) 중첩 함수
  function getFullName() {
    return firstName + " " + lastName;
  }

  alert( "Hello, " + getFullName() );
  alert( "Bye, " + getFullName() );

}

 

 

 

 

렉시컬 환경 (Lexical Environment)

: 자바스크립트에서 실행중인 함수, 코드블록, 스크립트 전체가 가지는

  내부 숨김 연관 객체 (internal hidden associated object)

: 변수는 특수 내부 객체인 환경 레코드의 프로퍼티임

: 명세서에서 자바스크립트가 어떻게 동작하는데 쓰이는 이론상의 객체

: 코드로 조작 불가

 

- 환경 레코드 (Environment Record)

: 모든 지역 변수를 프로퍼티로 저장하고 있는 객체

: this 값과 같은 기타 정보가 저장됨

 

- 외부 렉시컬 환경에 대한 참조

: 외부 코드와 연관됨

 

- 전역 렉시컬 환경

: 스크립트 전체와 관련된 렉시컬 환경

 

 

 

 

전역 렉시컬 환경의 변화

1. 스크립트가 시작되면 스크립트 내에서 선언한 변수 전체가 렉시컬 환경에 올라감

: 이 때 변수의 상태는 특수 내부 상태인 uninitialized가 됨

: 자바스크립트 엔진이 'let 변수명' 코드를 만나기 전까지 이 변수를 참조할 수 없음

 

2. 'let 변수명' 코드를 컴파일하면 해당 변수의 값은 undefined가 됨 

 

3. 해당 변수에 값이 할당 될 때 값이 생김

 

 

 

 

함수 선언문

: 함수는 일반 변수와 달리 바로 초기화 됨

: 함수 선언 문으로 선언한 함수는 렉시컬 환경이 만들어지는 즉시 사용 가능

: 선언되기 전에도 함수를 사용할 수 있는 이유

: 변수에 함수를 하당한 함수 표현식은 해당하지 않음

 

 

 

 

내부와 외부 렉시컬 환경

: 함수가 호출 중인 동안에는 함수를 위한 내부 렉시컬 환경과 내부 렉시컬 환경이 가리키는 외부 렉시컬 환경을 가짐

: 내부 렉시컬 환경은 외부 렉시컬 환경에 대한 참조를 가짐

: 코드에서 변수에 접근할 때는 먼저 내부 렉시컬 환경을 검색 범위로 잡음

: 내부 렉시컬 환경에서 원하는 변수를 찾지 못하면 검색 범위를 내부 렉시컬 환경이 참조하는 외부 렉시컬 환경으로 확장

: 이 과정은 검색 범위가 점역 렉시컬 환경으로 확장될 때까지 반복

: 전역 렉시컬 환경에 도달할 때 까지 변수를 찾지 못하면 엄격 모드에서는 에러 발생

: 하위 호환성을 위해 비 엄격 모드에서는 정의 되지 않은 변수에 값을 할당 하려고 할 시 새로운 전역 변수가 만들어짐

 

 

 

함수를 반환하는 함수

function makeCounter() {
  let count = 0;

  return function() {
    return count++;
  };
}

let counter = makeCounter();

: 위 예시에서 makeCounter()를 호출하면 호출할 때마다 새로운 렉시컬 객체가 만들어지고 

 여기에 makeCounter를 실행하는데 필요한 변수들이 저장됨

: 모든 함수는 함수가 생성된 곳의 렉시컬 환경에 대한 참조를 [[Environment]]라는 숨김 프로퍼티에 저장

: counter()를 여러번 호출하면 count 변수가 증가하는 이유임

 

 

 

 

※ 클로저 (closure)

: 외부 변수를 기억하고 이 외부 변수에 접근할 수 있는 함수

: 자바스크립트에서는 모든 함수가 클로저가 됨

 

 

 

 

가비지 컬렉션

: 호출이 끝난 후에 가비지 컬렉션에 의해 삭제되지 않는 중첩함수는 

  중첩함수의 [[Environment]] 프로퍼티에 외부 함수 렉시컬 환경에 대한 정보가 저장되어

  도달 가능한 상태이기 때문

function f() {
  let value = 123;

  return function() {
    alert(value);
  }
}

let g = f(); // g.[[Environment]]에 f() 호출 시 만들어지는
// 렉시컬 환경 정보가 저장됩니다.
function f() {
  let value = 123;

  return function() {
    alert(value);
  }
}

let g = f(); // g가 살아있는 동안엔 연관 렉시컬 환경도 메모리에 살아있습니다.

g = null; // 도달할 수 없는 상태가 되었으므로 메모리에서 삭제됩니다.

 

 

 

 

최적화 프로세스

: 이론상으로는 함수가 살아있는 동안에는 모든 외부 변수가 메모리에 유지 되지만

  실제 자바스크립트 엔진이 이를 지속해서 최적화를 수행

: 자바스크립트 엔진은 변수 사용을 분석하고 외부 변수가 사용되지 않는다고 판단되면

  이를 메모리에서 제거함

 

 

 

 

var

: 자바스크립트 초기에 사용하던 변수형

: const나 let과 달리 블록 스코프가 없어 함수 스코프 혹은 전역 스코프로 작동하기 때문에

  블록 밖에서도 접근이 가능

: var 선언은 함수가 시작 될 때 처리되며 선언 위치와 상관없이 함수 본문이 시작되는

  지점에서 정의됨

 

 

 

 

즉시 실행 함수식

: 선언과 동시에 실행되는 함수

// IIFE를 만드는 방법

(function() {
  alert("함수를 괄호로 둘러싸기");
})();

(function() {
  alert("전체를 괄호로 둘러싸기");
}());

!function() {
  alert("표현식 앞에 비트 NOT 연산자 붙이기");
}();

+function() {
  alert("표현식 앞에 단항 덧셈 연산자 붙이기");
}();

 

 

 

 

 

 

 

Refference

 

변수의 유효범위와 클로저

 

ko.javascript.info

 

오래된 'var'

 

ko.javascript.info

 

300x250
728x90