This week I learned - 변수 스코프 & for, forEach, for in, for of 차이

wondernova·2019년 9월 19일
0

TWIL-Javascript

목록 보기
1/2
post-thumbnail

1) 변수 스코프: let, var ,const 차이

  • let은 변수선언의 유효범위는 block{} 단위이며,
  • const는 변수선언의 유효범위가 block{}단위이며,
    let과 const의 차이는 let은 변수 재할당이 가능하나, const는 변수 재할당이 불가능하다.
  • var는 변수선언의 유효범위가 function() 단위이다.
var변수 선언을 할 경우,아래와 같이 for loop바깥에서도 여전히 변수 i값에 접근 할 수 있다.
for(var i; i<5; i++){
 console.log(i)  
}
console.log("i값",i) // 5 출력
let변수 선언을 할 경우,변수의 유효범위가 {} 범위이므로 아래와 같이 for loop바깥에서 변수 i값에 접근 할 수 없다.
for(let i; i<5; i++){
 console.log(i)  // 5
}
console.log("i값",i) // Reference Error 

- 호이스팅(Hoisting)

호이스트란, 변수의 정의가 그 범위에 따라 선언(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 에러를 발생시키게 되는 것이다.

2) for, forEach, for in, for of 차이

보통 자바스크립트에서 반복문의 형태중
"기본 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
profile
프로그래밍 스터디 정리 로깅입니다!

0개의 댓글