boolean, string, number
undefiend : 변수는 존재하나, 어떠한 값으로도 할당되지 않아 자료형이 정해지지(undefined
) 않은 상태입니다.
null : 변수는 존재하나, null
로 (값이) 할당된 상태. 즉 null
은 자료형이 정해진(defined
) 상태입니다.
symbol : 심볼은 객체 속성(object property)을 만들 수 있는 원시 데이터 형식(primitive data type) 이다. 정의하면 독립적인 값이 되기때문에, 같은 string 으로 정의해도 같은 값이 아니다.
object
let
과 const
는 block-scoped
이고 var
는 function-scoped
이다.
let
과 const
는 재선언이 불가능하다.
let
과 const
의 차이점은 변수의 immutable 여부이다.
let
은 변수에 재할당이 가능하지만, const
는 변수 재선언, 재할당이 모두 불가능하다.
function-scoped
& block-scoped
?function-scoped
var
는 그 함수의 코드블록 전체가 스코프이다. 전역함수에서 생성된 변수는 모두 전역 변수이다.for
문의 변수 선언문에서 선언한 변수를 for
문의 코드블록 외부에서 참조할수 있다.console.log(i) //undefined..정의는 되어있지만 값만 없는 상태
for(var i = 0; i < 10; i++){
}
console.log(i) //10
var
는 변수 선언(var i
)과 초기화(i = undefined
)가 한번에 이루어진다.block-scoped
console.log(i) //error . i is not defined
for(let i = 0; i < 10; i++){
}
console.log(i) //error i is not defined
i
를 var
로 선언하게 되면, 끌어올림이 발생하여 할당(assign)을 하지 않아도 정의가 되어있습니다.let
과 const
같은 block-scoped
는 선언을 하고 자신의 유효범위(해당 블록)안에서만 쓸 수 있습니다. 지역변수와 같은 개념입니다.
var
의 hoisting
// var는 function-scope이기 때문에 for문이 끝난다음에 j를 호출하면 값이 출력이 잘 된다.
// 이건 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
아래의 경우에는 에러가 발생한다.
```java
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
javascript에서는 immediately-invoked function expression (or IIFE, pronounced "iffy")
라는것이 있다.
IIFE
로 function-scoped
인거 처럼 만들 수가 있다.
// 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
위에서 잠깐 말했지만 IIFE
는 function-scoped
처럼 보이게 만들어주지만 결과가 같지는 않다.
// 이 코드를 실행하면 에러없이 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
위에 코드가 아무 에러 없이 실행되는 이유는 i
가 hoisting이 되어서 global variable
이 되었기 때문이다.
그래서 아래와 같이 된 것이다.
var i
(function() {
for(i=0; i<10; i++) {
console.log('i', i)
}
})()
console.log('after loop i is', i) // after loop i is 10
IIFE
는 쓰는데 이렇게 hoisting이 된다면 무슨 소용이 있겠는가?!
그래서 이런 hoisting을 막기 위해 use strict
를 사용한다.
// 아까랑 다르게 실행하면 i is not defined라는 에러가 발생한다.
(function() {
'use strict'
for(i=0; i<10; i++) {
console.log('i', i)
}
})()
console.log('after loop i is', i) // ReferenceError: i is not defined
let
,const
의 hoisting
let
, const
가 hoisting이 발생하지 않는건 아니다.
var
가 function-scoped
로 hoisting이 되었다면
let
, const
는 block-scoped
단위로 hoisting이 일어나는데
c = 'test' // ReferenceError: c is not defined
let c
위에 코드에서 ReferenceError
가 발생한 이유는 tdz(temporal dead zone)
때문이다.
let
은 값을 할당하기전에 변수가 선언 되어있어야 하는데 그렇지 않기 때문에 에러가 난다.
이건 const
도 마찬가지인데 좀 더 엄격하다.
// let은 선언하고 나중에 값을 할당이 가능하지만
let dd
dd = 'test'
// const 선언과 동시에 값을 할당 해야한다.
const aa // Missing initializer in const declaration