책 인사이드 자바스크립트의 내용을 참고하였습니다.
function init(){
var name = "Mozila';
function displayName(){
alert(name);
}
displayName();
}
init();
function makeFunc(){
var name = 'Mozila';
function displayName(){
alert(name);
}
return displayName;
}
var myFunc = makeFunc();
myFunc();
return
하면 외부에서의 호출이 가능해진다.이는 함수가 Closure
를 만들기 때문이다.
이미 생명 주기가 끝난 외부 함수의 변수를 참조하는 함수를 클로져라고 한다. 여기서는 이미 실행이 끝난 makeFunc
의 name 변수를 참조하는 displayName
함수가 클로저가 된다.
makeFunc의 실행 컨텍스트는 사라졌지만, makeFunc의 변수 객체는 여전히 남아있고 displayName의 스코프체인으로 참조되고 있다.
클로저란 함수와 함수가 선언된 곳의 lexical environment을 모두 포함한 곳이다. 이 environment는 closure가 만들어진 시점에 스코프 안에 있던 모든 local varible들로 이루어져 있다. 이 경우의 myFunc은 makeFunc이 실행되었을 때 만들어진 displayName의 인스턴스를 참조하고 있다.
displayName의 인스턴스는 변수 name이 존재하는 자신의 lexical environment에 대한 참조를 유지한다. 이 이유로 myFunc이 호출되었을 때 name 변수가 Mozila 값을 alert에 전달해줄 수 있는 것이다.
{
const name = "Alan"
}
console.log(name);
// Uncaught ReferenceError: name is not defined
name이 정의되지 않았다는 오류가 발생한다.
변수나 constant의 범위(Scope)가 뜻하는 바는 해당 변수가 어느 범위까지 접근이 가능한지 나타낸다.
let이나 const 로 선언한 변수는 변수가 정의 되어 있는 블록 , { } 안에서만 접근이 가능하다. 따라서 2) 에서의 console.log가 실행되는 전역 스코프에서는 name 변수를 찾을 수 없는 것이다.
function start(){
const message = "hi";
if(true){
const another = 'bye';
}
console.log(another)
}
함수, if, for 문 모두 { }으로 구성 되어 있다. 위 코드의 if 문 내에서 정의된 another 변수도 if 밖을 벗어나지 못하기 때문에 아래 console.log(another) 은 ReferenceEffor
에러를 낸다.
✔️ 전역변수는 프로그램 내 어디에서든지 접근이 가능하고 수정할 수 있기 때문에 각종 버그나 문제를 일으킬 수 있다. 따라서 전역 변수는 최대한 만들지 말아야한다.
참고
잘 봤습니다