자바스크립트는 총 세개의 변수가있는데 그차이를 살펴보도록합시다.

변수선언방식

var 이름;//재선언 o 재할당 o 범위 function
let 나이;//재선언 x 재할당 o 범위 { }
const 성별= 0;//재선언 x 재할당 x 범위 { }

1.재선언

var 이름 = 1;
console.log(이름) //1
var 이름 = 2
console.log(이름)//2

var같은 애들은 다시선언해줘도 따로도는 속성을 가지고있습니다.

변수이름이 같아서 헷깔리는 문제가 많이생기겠죠 

그래서 나온게 let ,const 입니다 애네들은 재선언x

2.재할당

var 변수 = 1;
변수 =2;
console.log(변수);//2
let 변수2 = 3;
변수2 = 5;
console.log(변수2)//5
const 변수3 =3;
변수 3 = 5;
console.log(변수3)//에러납니다

이렇듯 값을 복사하는게 재할당입니다

3.범위

각각의 변수의 적용범위가 어디까지 되는지 나타낸거에요

 

호이스팅

호이스팅(Hoisting)이란, var 선언문이나 function 선언문 등을 해당 스코프의 선두로 옮긴 것처럼 동작하는 특성을 말한다.

자바스크립트는 ES6에서 도입된 let, const를 포함하여 모든 선언(var, let, const, function, function*, class)을 호이스팅한다.

하지만, var 로 선언된 변수와는 달리 let 로 선언된 변수를 선언문 이전에 참조하면 참조 에러(ReferenceError)가 발생한다.

console.log(foo); // undefined
	var foo;

	console.log(bar); // Error: Uncaught ReferenceError: bar is not defined
	let bar;

 

이는 let 로 선언된 변수는 스코프의 시작에서 변수의 선언까지 일시적 사각지대(Temporal Dead Zone; TDZ)에 빠지기 때문이다.

참고로, 변수는 선언 단계 > 초기화 단계 > 할당 단계 에 걸쳐 생성되는데

var 으로 선언된 변수는 선언 단계와 초기화 단계가 한번에 이루어진다. 하지만,

// 스코프의 선두에서 선언 단계와 초기화 단계가 실행된다.
// 따라서 변수 선언문 이전에 변수를 참조할 수 있다.

console.log(foo); // undefined

var foo;
console.log(foo); // undefined

foo = 1; // 할당문에서 할당 단계가 실행된다.
console.log(foo); // 1

let 로 선언된 변수는 선언 단계와 초기화 단계가 분리되어 진행된다.

// 스코프의 선두에서 선언 단계가 실행된다.
// 아직 변수가 초기화(메모리 공간 확보와 undefined로 초기화)되지 않았다.
// 따라서 변수 선언문 이전에 변수를 참조할 수 없다.

console.log(foo); // ReferenceError: foo is not defined

let foo; // 변수 선언문에서 초기화 단계가 실행된다.
console.log(foo); // undefined

foo = 1; // 할당문에서 할당 단계가 실행된다.
console.log(foo); // 1

Reference Data Type

var name = 'john';
var age = 20;
// Primitive data type들은 그냥 별건 없고 자료 자체가 변수에 저장되는 자료들입니다. 

// 문자, 숫자 자료형들이 대표적인 primitive data type들입니다. 

var 사람 = { name : 'Kim' };
// 여러분 방금 { name : 'Kim' } 이라는 자료를 변수에 저장했습니다. 

// 하지만 변수에 저장된건 { name : 'Kim' } 이게 아닙니다. 

// "{ name : 'Kim' }이 저기 저장되어있습니다"라는

// { name : 'Kim' } 값을 가리키는 화살표가 저장이 되어있을 뿐입니다

// Q. 화살표가 가리키는 저기가 어딘데요?

// A. 컴퓨터 메모리 상의 어떤 곳입니다.
//그래서 reference data type은 신기한 현상들이 일어납니다

 

 

 

 

예제1

 

함수();
function 함수() {
  console.log(안녕);
  let 안녕 = 'Hello!';
} 
//함수 실행전에 함수선언전에 해도 되냐?가능 호이스팅이 되기때문
//근데 문제가 뭐냐 안녕 만들기전에 안녕을 출력해서 에러가남
//변수가 할당되지않고 호이스팅되지않음 let,const는 hoisting시 undefined할당안됌

예제2

함수();
var 함수 = function() {
  console.log(안녕);
  var 안녕 = 'Hello!';
} 
//이거는 함수인데함수가아니라고 에러가남
//function 함수() { 전부 hoistiong됌
    
//}

예제3

let a = 1;
var 함수 = function() {
  a = 2;
}
console.log(a);//1이나옴 함수만들기만하고 실행을안했잖음.

let a = 1;
var b = 2;
window.a = 3;
window.b = 4;

console.log(a + b);
//b는 4가 나옴
//전역변수는 상위값보단 가까이 있는 변수값을 쓰려고하기때문에 a=1이됍니다.
//값은 5가나옴

예제4

setTimeout(function() { console.log(1); }, 1000 ); 
setTimeout(function() { console.log(2); }, 2000 ); 
setTimeout(function() { console.log(3); }, 3000 ); 
setTimeout(function() { console.log(4); }, 4000 ); 
setTimeout(function() { console.log(5); }, 5000 ); 

for (let i = 1; i < 6; i++) { 
    let i =0;
    setTimeout(function() { console.log(i); }, i*1000 ); 
  }
  //{ console.log(i); }는 바로 실행되는 코드강아님 1~5초뒤에 실행됌
  //빠르게 5번이 돌고난다음 안에 있는 함수를 실행시키는거임
  //var를 let으로 변경시키면됌

예제5

<div style="display : none">모달창0</div>
<div style="display : none">모달창1</div>
<div style="display : none">모달창2</div>

<button>버튼0</button>
<button>버튼1</button>
<button>버튼2</button>

<script>
  //?
var 버튼들 = document.querySelectorAll('button');
var 모달창들 = document.querySelectorAll('div');

버튼들[0].addEventListener('click', function(){
  모달창들[0].style.display = 'block';
});

버튼들[1].addEventListener('click', function(){
  모달창들[1].style.display = 'block';
});

버튼들[2].addEventListener('click', function(){
  모달창들[2].style.display = 'block';
});
for (var i = 0; i < 3; i++){

버튼들[i].addEventListener('click', function(){
  모달창들[i].style.display = 'block';
});

}
</script>

 

복사했습니다!