함수에 의해 생기는 유효 범위
블럭에 의해 생기는 유효 범위 => {}
ex) {}, if문, for문, while문, switch문
// var는 function-scope이기 때문에 for문이 끝난다음에 i를 호출하면 값이 출력이 잘 된다.
// 이건 var가 hoisting이 되었기 때문이다.
for(var j=0; j<10; j++) {
console.log('j', j)
}
console.log('after loop j is ', j) // after loop j is 10
-----------
다음과 같다.
-----------
var j;
for(j=0; j<10; j++) {
console.log('j', j)
}
console.log('after loop j is ', j) // after loop j is 10
// 아래의 경우에는 에러가 발생한다.
function counter () {
for(var i=0; i<10; i++) {
console.log('i', i)
}
}
counter()
console.log('after loop i is', i) // ReferenceError: i is not defined
이 현상을 해결하기 위해선 IIFE (즉시 실행 함수) 형태로 바꿔주면 된다
// IIFE를 사용하면
// i is not defined가 뜬다.
(function() {
// var 변수는 여기까지 hoisting이 된다.
for(var i=0; i<10; i++) {
console.log('i', i)
}
})()
console.log('after loop i is', i) // ReferenceError: i is not defined
// 이 코드를 실행하면 에러없이 after loop i is 10이 호출된다.
(function() {
for(i=0; i<10; i++) {
console.log('i', i)
}
})()
console.log('after loop i is', i) // after loop i is 10
var i = 10;
var i = 20;
function hasValue (p) {
console.log(v); // ReferenceError: v is not defined
if(p){
let v = 'blue'
console.log(v)
}else{
let v = 'red'
console.log(v)
}
console.log(v); // v is not defined
}
hasValue(10)
const obj = {a: 1, b: 2};
obj.a = 3;
console.log(obj.a); // 3
변수 선언의 끌어올림.
프로그램에서 변수가 중간에서 선언되더라도 변수가 프로그램 첫 머리에 선언되는 것처럼 다른 문장앞에서 생성하는 것을 호이스팅이라고 한다.
변수 선언만 위로 끌어올리고 undefined를 할당했다.
(function() {
var a = 10;
(function() {
console.log(a); // undefined
var a = 20;
})();
console.log(a); // 20
})();
console.log(a); // ReferenceError: a is not defined, 함수 스코프이므로 외부에선 not defined
if(true){
let a = 10
if(true){
// ReferenceError: Cannot access 'a' before initialization
console.log(a); // 호이스팅은 하되 값을 할당하지 않음.
const a = 20; // console 전에 선언하면 가능
}
console.log(a); // let a
}
console.log(a); // not defined
var c = 30
console.log(window.c) // 30
console.log(c) // 30
delete c // var로 선언된 c는 전역변수 이자 전역객체이기 때문에 삭제할 수 없어 false
console.log(window.c) // 30
console.log(c) // 30
전역변수 범위에서 var 변수 선언시 전역객체의 프로퍼티와 전역변수로 선언이 된다.
let b = 10 // const 도 동일
console.log(window.b) // undefined
console.log(b) // 10
delete b // false b는 전역객체의 프로퍼티가 아니므로 삭제 안됨.