for(var i; i<5; i++){
console.log(i)
}
console.log("i값",i) // 5 출력
for(let i; i<5; i++){
console.log(i) // 5
}
console.log("i값",i) // Reference Error
호이스트란, 변수의 정의가 그 범위에 따라 선언(declaration)/초기화(initialization)/할당 분리되는 것을 의미하는데,
변수가 함수내에서 정의되었을 경우 선언이 함수의 최상위로, 함수 바깥에서 정의되었을 경우는 전역 컨텍스트의 최상위로 변경된다.
예제 코드를 보며 살펴보자.
console.log(ar) // undefined
var ar = 'hello'
위의 코드에서 첫줄에 ar을 콘솔로 출력시 에러가 나지 않고 undefined처리 됨을 볼수 있는데,이는 실행시점에 호이스팅에 의해 var 변수가 최상단에 선언되기 때문이다.
그렇다면 let,const의 경우엔 어떻게 처리될까?
console.log(ar) //ReferenceError
let ar = 'hello'
실행을 해보면 ReferenceError가 뜨게 된다. 하지만 이것이 let,const가 호이스팅이 되지 않는다는걸 의미하는건 아니다.
아래의 예제를 다시 보면,
var ar = 'hello' // 전역변수
{
console.log(ar) //ReferenceError
let ar = 'hello2' // 지역변수
}
최상단에 ar 변수를 선언했는데도,에러가 뜨는 이유는 {} 블록 스코프내에 let으로 선언된 ar 변수가 호이스팅 되었기 때문이다. let ar 변수가 호이스팅 되지 않았다면 console.log의 결과는 전역변수 ar이 가리키는 'hello'가 출력되어야 한다.
따라서 let,const 도 호이스팅이 되는걸 알수 있는데,
왜 var의 경우 undefined가 나오지만 let의 경우 ReferenceError를 뱉어내는가?
위에서도 언급하였듯이, 변수는 '선언단계','초기화 단계','할당단계'를 통해 생성되는데,"var 로 선언된 변수는 호이스팅 되어 선언과 초기화"가 동시에 이뤄지기 때문에 undefined로 출력이 되는걸 알수 있다.
* 선언단계 : 변수를 실행컨텍스트의 변수객체에 등록한다.
* 초기화 단계 : 실행 컨텍스트에 등록 된 변수객체에 대한 메모리를 할당한다. 이 단계에서 변수는 undefined로 초기화 된다.
* 할당단계 : undefined로 초기화 된 변수에 값을 할당한다.
그러나 let으로 선언된 변수는 호이스팅 되어 선언단계가 이뤄지지만 초기화 단계는 실제 let이 사용된 코드에 도착했을 때 이뤄지기 때문에, 초기화 단계 이전에 변수에 접근하면 reference 에러를 발생시키게 되는 것이다.
보통 자바스크립트에서 반복문의 형태중
"기본 for문, forEach, for of, for in"의 차이는 아래와 같다.
forEach 문
forEach 반복문은 Array 객체에서만 사용가능한 메서드로, 배열의 요소들을 반복하여 작업수행할 때 사용된다. forEach 구문의 인자로 callback함수를 등록하여, 배열의 각 요소들이 반복될때 callback함수가 호출되며 callback함수에서 배열의 요소와 인덱스,배열에 접근할 수 있다.
- array.forEach(callbackFunction(currnetValue, index, array), thisArg): forEach의 콜백함수의 매개변수는 3가지로,
첫번째는 해당값, 두번째는 index, 세번째는 배열이다.
var arr = ['A', 'B', 'C'];
arr.forEach(function(item,i) {
console.log(item,i);
});
//결과
// A 0 // 배열요소, 인덱스
// B 1
// C 2
for of 문
"forEach"와 "for of" 는 "배열의 반복"에 주로 사용되는데,
for of는 컬렉션 객체가 [Symbol.iterator] 속성을 가지고 있어야 사용가능한 메서드로,
만약 array가 아닌 object로 변경된 변수에 해당 메소드를 사용하면 에러발생한다는 점에 유의!
for Each와 for of의 차이는 foreach의 경우 callback함수가 필요하나,for of는 callback 함수를 쓸 필요없이 배열요소에 접근let arr1 =['ak','jk','ar'] for(let k of arr1){ console.log(k) } // ak ## 배열 요소 출력 // jk // ar
for in 문
for in 반복문은 객체의 속성들을 반복하여 작업을 수행할 때 사용할수 있으며, 모든 객체에서 사용이 가능하다. for in 구문은 객체의 key 값에 접근할 수 있지만, value 값에 접근하는 방법은 제공하지 않는다는점에 유의.
let obj = { a: 1, b: 2, c: 3 }; for (let key in obj){ console.log(key); } //a 객체의 키 값 출력 //b //c