Javascript Closure & Lexical Scope
■ Lexical Scope
1) 정의:
함수가 함수 밖에서 참조하는 변수는
함수의 선언 영역에서 참조가능한 global 변수를 참조
=== 함수의 선언 영역에 따라 상위 스코프가 결정(함수의 호출이 결정하지 않음)
var number = 1;
function a() {
var number = 10;
b();
}
function b() {
console.log(number);
}
a(); // 1
b(); // 1
※ 함수의 호출에 따른 결정방식을 따르면 Dynamic Scoping이라고 함
> Java, C 등 요즘 언어는 lexical scope
2) 상위스코프의 범위
> 찾을 때 까지 상위 범위로 확장
( 지역 scope에서 못찾으면 parent 상위 scope으로 확장 )
let name = "Chrome"
function init() {
let name = 'Mozilla'; // name is a local variable created by init
function displayName() { // displayName() is the inner function, a closure
alert(name); // use variable declared in the parent scope
}
displayName();
}
init();
>>> Mozilla 출력!
let name = "Chrome"
function init() {
function displayName() { // displayName() is the inner function, a closure
alert(name); // use variable declared in the parent scope
}
displayName();
}
init();
>>> Chrome 출력!
■ Closure
1) 정의 :
클로져는 함수와, 그 함수가 선언되었을 때 scope안의 lexical 환경을
함수 자체와 함수의 환경의 조합으로 저장하는 것
> 때문에 부모 함수의 실행이 종료되더라도, lexical에 포함된 Scope에 접근할 수 있음
> 코드적으로는 함수 자체를 return으로 받으면서 closure 생성
function makeFunc() {
var name = 'Mozilla';
function displayName() {
alert(name);
}
return displayName;
}
// 함수 자체를 return 받으면서 closure 생성
// name variable은 makeFunc() 이후 지워지지 않고 closure 때문에 지속적으로 존재
var myFunc = makeFunc(); // displayName이 참고하는 lexical scope 모두를 가지고 있는 상태
myFunc();
>>> Mozilla 출력!
2) 사용법
> 즉시 실행함수
> counter 함수 등 calling으로 따로 관리 하고싶을 때 다음과 같이 사용
( 다른 변수들과 겹치거나 다른 곳에서 같은 이름으로 사용되어서 변수값이 바뀔 우려 등 때문 )
var addNum = (function() {
var count = 0;
return function() {
count += 1;
return count;
}
})();
addNum();
addNum();
console.log(addNum()) // 3
> 위의 예시는
closure로 함수를 선언하고 count 올릴 때
즉시실행함수(자기실행함수) - self-invoking function으로 올리고 있다
■ 즉시실행함수
★ 중요 참조 : devyj.tistory.com/9
> 사용 이유
- 글로벌 scope에 정의된 것은 코드 어느 부분이든 접근 가능,
- 외부 공유되면 안되는 속성, 메써드 / 다른 script 파일에서 동일한 이름의 변수나 함수 있을 시 원치 않는 결과 초래
- 따라서 위를 방지하고자 사용
> 사용방법
( ) 괄호로 function을 wrapping
// 즉시실행함수
//(1)번 방식
(function() {
console.log('함수 호출'); // "함수 호출" 출력
}());
//(2)번 방식
(function() {
console.log('함수 호출'); // "함수 호출" 출력
})();
※ 참조 : 함수선언방식의 차이
1) 함수 선언 방법
(a-1) 함수표현식에 의한 함수호출
> Hoisting에 영향받지 않아 선언시점보다 사용시점이 뒤에 위치해야 error 발생하지 않음
> var / let const 등의 경우 선언이 위로 끌어올려지기 때문 (let const는 실제 사용전 까지 undefined 취급)
> 함수를 뒤에 할당하였더라도 변수로 인식되는 이유
// 함수표현식에 의한 명시적인 함수호출
var app = function() {
console.log('함수 호출'); // "함수 호출" 출력
};
app();
> 사용이점
- 클로져로 사용 가능
- 콜백으로 사용 (다른 함수의 인자로 전달 가능)
> 변수 할당하지 않고 다른 함수의 param으로 넘기기 : 익명함수
> 스크립트 로딩 시점에 VO(변수객체)에 함수를 할당하지 않음
(a-2) 함수선언식에 의한 명시적 함수호출
> Hoisting에 영향을 받아 해석 시작시 맨 위로 끌어올려진다, 선언시점 관계 없음
> 스크립트 로딩 시점에 VO(변수객체)에 함수를 할당함
> 너무 많은 함수들을 VO에 저장하면 app의 응답속도가 줄어듦으로, 주의를 요함
// 함수표현식에 의한 명시적인 함수호출
function app() {
console.log('함수 호출'); // "함수 호출" 출력
};
app();
(b) 익명함수 + 즉시실행 = 익명 즉시실행함수
- 즉시실행함수는 한 번의 실행만 필요로 하는 초기화 코드에 많이 사용
var initText;
(function (number) {
var textList = ["is Odd Text", "is Even Text"];
if (number % 2 == 0) {
initText = textList[1];
} else {
initText = textList[0]; }
})(5);
console.log(initText); // odd text, 선언, 초기화, 할당까지 즉시실행함수에서 담당
console.log(textList); // not defined
- 즉시 실행함수 내부 변수는 global scope으로 사용이 안됨 → 충돌 걱정없이 사용
※ 원래 지역변수는 바깥 scope에서 참조 불가능하고, 즉시실행으로 함수표현식으로 변수에 함수할당 없이
바로 함수를 실행할 수 있으므로 → 깔끔하게 'global scope와 분리된 어떤 동작' 을 수행할 수 있음
- 라이브러리 전역 변수의 충돌
> jQuery나 Prototype 라이브러리는 동일한 $라는 전역 변수를 사용
(function ($) {
// $ 는 jQuery object
// scope 밖에있는 변수, elem등을 쓰고 Prototype의 $와 상관이 없게 됨
...
})(jQuery);
> function 내부의 변수를 private하게 선언하고 저장, return등으로 글로벌에서 access 조정 가능
var app = (function() {
var privateVar = 'private';
return {
prop : privateVar
};
}());
console.log(app.prop); // "private" 출력
참조 :
medium.com/@yeon22/javascript-lexical-scope-static-scope-and-dynamic-scope-c4a9e941fab3
(JavaScript) Lexical Scope(Static Scope) and Dynamic Scope
프로그래밍에서 Scope란 변수의 유효범위를 나타내는 용어인데요(Scope에 대한 자세한 사항은 이전의 글을 참고해주시기 바랍니다).
medium.com
[JS/클로져] 자바스크립트의 Lexical scoping과 Closure
하.. 너무 이해하기 어렵고 힘들었는데 최대한 MDN이랑 W3Cschools 글을 읽고 또 읽어서 이해한 내용을 정리해보려고 한다. 내가 정리한 내용들은 모두 아래 링크로 들어가면 나온다. Closures A closure i
im-developer.tistory.com
[자바스크립트] 함수(Function), 즉시실행함수(Immediately-invoked function expression)
함수(Function) 1. 함수 선언(Function declaration 혹은 Function statement) 함수 선언(Function declaration)을 MDS에서 밑에와 같이 정의 하였습니다. 문법 function name([param,[, param,[..., param]]]) {..
beomy.tistory.com