const adder = function (x) {
return fucntion (y) {
return x + y;
}
}
// 외부를 감싸고 있는 '외부 함수'는 y에 접근 할 수 없다.
// 내부에 있는 '내부 함수'는 x에 접근 할 수 있다.
클로저가 가장 유용하게 사용되는 상황은 현재 상태를 기억하고, 변경된 최신 상태를 유지해야할 때.
데이터를 보존하는 함수 : 외부 함수의 실행이 끝나더라도 외부 함수 내의 변수를 사용할 수 있음.
이는 외부 함수 내 변수가 메모리 상에 저장되기 때문인데, ‘어휘적인 환경’을 메모리에 저장하기 때문에 가능한 것!
const adder = function (x) {
return function (y) {
return x + y;
}
}
const add5 = adder(5);
add5 (7) // 12
add5 (10) // 15
// add5라는 변수에는 adder 함수에 5를 인자로 전달한 값이 그대로 유지되고 있음.
// 그래서 add5 함수에 다른 값을 넣으면 내부에 있는 함수에 인자가 전달이 되어 처리됨.
const tagMaker = tag => content => `<${tag}>${content}</${tag}>`
const divMaker = tagMaker('div');
divMaker('hello')// <div>hello</div>
divMaker('codestates')// <div>codestates</div>
const anchorMaker = tagMaker('a')
anchorMaker('go') // <a>go</a>
anchorMaker('urclass') //<a>urclass</a>
const makeCounter = () => {
let value = 0;
return {
increase: () => {
value = value + 1
},
decrease: () => {
value = value - 1
},
getValue: () => value
}
}
const counter1 = makeCounter();
counter1 // 객체인 {increase: f, decrease: f, fetValue: f }를 리턴.
//makeCounter 함수를 바꾸지 않고서 value 값을 새롭게 할당할 수 없지만 리턴하는 객체가 제공하는 매서드를 통해 value 값을 간접적으로 조작할 수 있음.
//아래 모듈화 예시를 보면 value를 어떻게 간접적으로 수정할 수 있는지 알 수 있음.
//value 값을 전역 변수로 만들지 않아 side effect 방지 가능.
const counter1 = makeCounter();
counter1.increase();//1
counter1.increase();//2
counter1.decrease();//1
counter1.getValue();//1을 리턴
const counter2 = makeCounter()
counter2.decrease();//-1
counter2.decrease();//-2
counter2.decrease();//-3
counter2.getValue();//-3을 리턴
//makeCounter에 의해 리턴된 객체는 makeCounter를 실행할 때 선언되는 value 값을 각자 독립적으로 가짐.
//counter1과 counter2에서의 value는 서로에게 영향 끼치지 않고 각각 값 보존 가능.
자바스크립트는 가비지 컬렉션을 통해 메모리 관리를 합니다. 객체가 참조 대상이 아닐 때, 가비지 컬렉션에 의해 자동으로 메모리 할당이 해제됩니다.
Execution context (실행 컨텍스트)
: 실행 가능한 코드가 실행되기 위해 필요한 환경
자바스크립트 엔진은 코드를 실행하기 위해 실행에 필요한 여러 정보를 알고 있어야 한다.
변수 : 전역변수, 지역변수, 매개변수, 객체의 프로퍼티
함수 선언
변수의 유효범위(scope)
this
실행에 필요한 정보를 형상화하고 구분하기 위해 자바스크립트 엔진은 실행 컨텍스트를 물리적 객체의 형태로 관리한다.
lexical environment : 자바스크립트 코드에서 변수나 함수 등의 식별자를 정의하는데 사용하는 객체로 Environment Record와 Outer Environment Reference를 프로퍼티로 가짐. ( ES5 이전에는 변수 객체, 활성화 객체, 스코프 체인등이 기능하던 것을 ES5 이후 lexical environment가 대신 기능하게 됨.)
참고 : https://iamsjy17.github.io/javascript/2019/06/10/js33_execution_context.html