자바스크립트 중급 - 클로저

김민재·2023년 1월 9일
0

TIL, Core JavaScript

목록 보기
10/11

어휘적 환경

let one;
one = 1;


function addOne(num) {
    console.log(one + num)
}

addOne(5) 
  • 자바스크립트는 어휘적 환경을 갖는데
    코드가 실행되면 스크립트 내에 선언한 변수들이 lexical Environment에 올라간다

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
  • 위 함수는 y를 갖고 상위 함수인 makeAdder의 x에 접근 가능하다
  • add3 함수 생성 이후에도 상위함수인 makeAdder의 x에 접근 가능한데 이를 클로저라고한다
  • 위 add3과 add10은 서로 다른 환경을 가지고 있으며 이렇게 클로저를 하면 변수를 은닉화하는 효과를 가질 수 있다.
profile
자기 신뢰의 힘을 믿고 실천하는 개발자가 되고자합니다.

0개의 댓글