꼬리를 물면서 계속 범위를 밖으로 넓혀나가며 변수를 찾는 관계
범위를 지정하는 과정에서 변수가 소스코드 내에 어디에서 선언되었는지를 고려한다는 의미
var name = 'zero'; // (1)변수 선언 (6)변수 대입
function wow(word) { // (2)변수 선언 (3)변수 대입
console.log(word + ' ' + name); // (11)
}
function say () { // (4)변수 선언 (5)변수 대입
var name = 'nero'; // (8)
console.log(name); // (9)
wow('hello'); // (10)
}
say(); // (7)
// 결과: nero hello zero
전역 컨텍스트
가 생긴다.함수 컨텍스트
가 생긴다.https://www.zerocho.com/category/JavaScript/post/5741d96d094da4986bc950a0
var name = 'zero'; // (1)변수 선언 (6)변수 대입
function wow(word) { // (2)변수 선언 (3)변수 대입
console.log(word + ' ' + name); // (11)
}
function say () { // (4)변수 선언 (5)변수 대입
var name = 'nero'; // (8)
console.log(name); // (9)
wow('hello'); // (10)
}
say(); // (7)
// 결과: nero hello zero
이 코드가 실행이 될 때 context 변화
'전역 컨텍스트': {
변수객체: {
arguments: null,
variable: ['name', 'wow', 'say'],
},
scopeChain: ['전역 변수객체'],
this: window,
}
say()
함수 호출될 때'say 컨텍스트': {
변수객체: {
arguments: null,
variable: ['name'], // 초기화 후 [{ name: 'nero' }]가 됨
},
scopeChain: ['say 변수객체', '전역 변수객체'],
this: window,
}
wow()
함수 호출될 때'wow 컨텍스트': {
변수객체: {
arguments: [{ word : 'hello' }],
variable: null,
},
scopeChain: ['wow 변수객체', '전역 변수객체'],
this: window,
}
이 때 lexical scoping에 따라서 scope chain이 함수 선언시에 정해져있다.
클로저를 설명할 때는 scope, context 개념을 함께 설명해야한다.
다음과 같은 코드가 있다.
var makeClosure = function() {
var name = 'zero';
return function () {
console.log(name);
}
};
var closure = makeClosure(); // function () { console.log(name); }
closure(); // 'zero';
이 때 전역 context, makeClosure의 context를 보면 다음과 같다.
"전역 컨텍스트": {
변수객체: {
arguments: null,
variable: [{ makeClosure: Function }, 'closure'],
},
scopeChain: ['전역 변수객체'],
this: window,
}
"makeClosure 컨텍스트": {
변수객체: {
arguments: null,
variable: [{ name: 'zero' }],
},
scopeChain: ['makeClosure 변수객체', '전역 변수객체'],
this: window,
}
그런데 closure를 만드는 상황, 즉, return function() ~ 하는 부분에서 context는 다음과 같다.
"closure 컨텍스트": {
변수객체: {
arguments: null,
variable: null,
scopeChain: ['closure 변수객체', 'makeClosure 변수객체', '전역 변수객체'],
this: window,
}
따라서 closure 함수에서 scope chain을 통해서 makeClosure의 name 변수에 접근할 수 있다.
이렇게 비공개로 변수를 만들어서 남들이 조작할 걱정을 덜 수 있다는 장점이 있다.
단점은 자바스크립트가 메모리 관리를 언제 해야할 지 모르기 때문에 메모리 낭비가 생길 수 있다는 단점이 있다.
다음 코드에서 의도한대로 실행 결과가 나오지 않는 이유는?
for (var i = 0; i < 5; i++) {
$('#target' + i).on('click', function() {
alert(i);
});
}