let one;
one = 1;
function addOne(num) {
console.log(one + num)
}
addOne(5)
1> let으로 선언된 변수는 호이스팅 되지만 초기화는 안되어있고 함수 선언문은 변수와는 달리 초기화 되어있어 바로 사용 가능
// 렉시컬 환경
one // 초기화 x
addOne// function
let one // undefined
one = 1
// 이미 초기화 완료
function addOne(num) {
console.log(one + num)
}
addOne(5)
2> 이후 let one을 만나고 값은 할당이 안되어있기에 undefined가 되고 이후 one에 값 1을 할당한다.
let one // undefined
one = 1
// 이미 초기화 완료
function addOne(num) {
console.log(one + num)
}
addOne(5)
// 결과
// 전역 레시컬 환경
/* one : 1
addOne function
*/
// 내부 렉시컬 환경
/* one : 5 */
3> 함수가 실행되면서 순간 새로운 렉시컬 환경을 만들어준다. 넘겨받은 매개변수와 지역변수들이 저장된다.
즉 함수가 호출되는 동안 함수 내부에서 만들어진
내부 렉시컬 환경과 외부에서 만들어진 전역 렉시컬 환경 총 2개의 환경을 가지게 된다
내부 렉시컬 환경은 외부 렉시컬 환경에 대한 참조를 갖기에 위 코드에선 변수를 찾을 땐 내부 렉시컬 환경에서 찾고 없으면 외부를 찾은뒤 없을 경우 전역 렉시컬 환경까지 범위를 넓혀서 찾는다
우선 one과 numd은 내부 렉시컬 환경에서 변수를 찾고 num은 찾았지만 one이 없으므로 외부로 넓혀서 찾게되어 함수를 실행해준다.
// 전역 렉시컬 환경 makeAdder, add3
function makeAdder(x) {
// makeAdder 렉시컬환경 x:3
return function (y) {
return x+y
}
}
const add3 = makeAdder(3) // 초기화 X
// 익명함수 렉시컬 환경 y:2
console.log(add3(2))
// 이후 x,y를 찾는다
최초 실행시 makeAdder 함수와 add3 변수 전역 렉시컬 변수에 들어가 있고 역시 add3는 초기화가 안되있다
add3 코드 실행 시 makeAdder 실행되며 렉시컬 환경 만들어 져 전달받은 x의 값이 들어가며 makeAdder 함수에 렉시컬 환경에는 전달받은 매개변수와 지역변수가 저장된다.
처음 add3(2)에서 y:2를 찾고 x가 없으니 외부 렉시컬 환경, makeAdder 렉시컬 환경에 가서 x를 찾을 수 있다.
function makeAdder(x) {
// makeAdder 렉시컬환경 x:3
return function (y) {
return x+y
}
}
const add3 = makeAdder(3)
console.log(add3(2)) // 5
const add10 = makeAdder(10)
console.log(add10(5)) // 15
console.log(add3(1)) // 4