책 인사이드 자바스크립트의 내용을 참고하였습니다.
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에러를 낸다.
✔️ 전역변수는 프로그램 내 어디에서든지 접근이 가능하고 수정할 수 있기 때문에 각종 버그나 문제를 일으킬 수 있다. 따라서 전역 변수는 최대한 만들지 말아야한다.
참고
잘 봤습니다