javascript-렉시컬환경

javascript 책 공부중 렉시컬 환경? 이라는 단어를 보고 이게 어떤것을 의미하는지 궁금하여 알아보았다. 역시 처음들어보는 생소한 의미였고 새로운것을 배웠다.
렉시컬 환경에 대해 알아보자.

👍렉시컬 환경

javascript에서 실행중인 함수, 코드 블록 { }, 스크립트는 렉시컬 환경이라 불리는 내부 숨김 연관 객체를 갖는다.

렉시컬 환경은 두가지로 나뉜다.

  1. 환경 레코드: 모든 지역변수를 프로퍼티로 저장하고 있는 객체.
  2. 외부 렉시컬 환경에 대한 참조: 외부 코드와 연관

환경 레코드

  • 모든 지역변수를 프로퍼티로 저장하는 객체
  • this 값과 같은 기타 정보도 저장된다.
  • 변수는 특수 내부 객체인 환경 레코드의 프로퍼티의 의미일 뿐이다.
  • 변수를 가져오거나 변경하는 것은 환경 레코드의 프로퍼티를 가져오거나 변경하는 것이다.

외부 렉시컬 환경

  • 외부 코드와 연결된다.

전역 렉시컬 환경

1
let a = 'hello';

위와 같이 선언된 변수는 코드 전체와 관련된 변수로 전역 렉시컬 환경이라고 부른다. 스크립트 전체와 관련된 전역 렉시컬 환경은 외부 참조를 가지지 않는다.

함수의 렉시컬 환경

함수는 선언과 동시에 렉시컬 환경이 만들어지는 즉시 사용히 가능하다.
함수를 선언하면 함수는 젼역 렉시컬 환경이 된다.

이후 함수를 호출할때 함수를 위한 내부 렉시컬 환경과 내부 렉시컬 환경이 가르키는 외부 렉시컬 환경을 갖게 된다.

1
2
3
4
5
6
7
8
let a = 'hello';
function say (name) {
// 함수 내부에서 내부 렉시컬 환경이 만들어짐
// 함수 호출시 내부 렉시컬 환경에는 name이라는 프로퍼티가 생성됨
// 또한 외부 렉시컬 환경을 참조한다.
console.log(`${a} ${name}`);
}
say('jone');

함수가 호출되고 내부 렉시컬 환경에 name이라는 프로퍼티를 생성하고 전역 렉시컬 환경을 외부 렉시컬 환경으로 참조한다.
이 후 함수는 변수에 접근할때 내부 렉시컬 환경에서 변수에 먼저 접근하고 내부 렉시컬 환경에 해당하는 변수를 찾지 못하면 참조하고 있는 외부 렉시컬 환경으로 넘어가 변수를 찾는다. 이 과정은 전역 렉시컬 환경으로 확장 될 때까지 반복된다.

따라서 say함수는 aname변수를 찾아야한다. 이때 내부에서 먼저 name이라는 변수를 찾고 내부 렉시컬 환경에 존재하지 않는 a변수를 찾기위해 외부 렉시컬 환경에서 찾아 값을 참조하는 방식으로 진행된다.

함수를 반환하는 경우의 렉시컬 환경

1
2
3
4
5
6
7
8
function makeCounter() {
let count = 0;

return function () {
return count++;
}
}
let counter = makeCounter();

makeCounter함수가 호출되면 함수의 새로운 렉시컬 환경이 생성된다.
makeCounter함수의 내부 렉시컬 환경에는 count라는 변수와 중첩함수가 만들어진다.

이때 생성한 중첩함수는 생성된 곳의 렉시컬 환경을 기억한다. 함수는 [[Environment]]이라는 숨김 프로퍼티를 가지는데 이것이 함수가 만들어진 곳의 렉시컬 환경에 대한 참조가 저장된다.

따라서 이 함수를 호출시 makeCounter의 내부 렉시컬 환경이 구성되고 내부의 중첩 함수는 자신이 생성된 외부 함수의 렉시컬 환경을 참조한다. 외부 함수의 내부 렉시컬 환경에 count라는 변수가 생성되고 중첩함수가 실행되는데 중첩 함수에서는 먼저 내부 렉시컬 환경에서 count라는 변수를 찾고 없기때문에 자신이 참조하는 외부 렉시컬 환경인 외부 함수의 렉시컬 환경에서 count변수를 찾아 증가시킨다.
이러한 방식으로 인해 makeCounter함수가 호출 될때마다 count의 값은 증가한다.

Author

han Ju Ryeon

Posted on

2021-10-11

Updated on

2021-12-05

Licensed under

댓글