본문 바로가기
JavaScript

2021.03.24 Java Script 변수 선언, 할당

by 해맑은 코린이 2021. 3. 24.

2021.03.24_Java Script 변수 선언, 할당 _정리노트

 

 

ㅎㅇㅎㅇ... 리액트 모달로 돌아온다 했다가 한달 뒤 이상한걸로 돌아와버린 나.....

이번 프로젝트 하면서 너무 반성을 많이 했기.. 때문에 맨날 자바스크립트 기초부터 처음부터 잘 다잡아야지 다잡아야지.. 하는데 정말 한달 뒤에나 블로그로 돌아오고 말았다. 요즘은 가끔씩 블로그 쓰면서 반성만 이따시만큼 하는 것 같은데.. 오늘도 역시 반성으로 다시 돌아왔다.

 

 

사실 블로그라는 공개적인 장소에서 리액트를 어떻게든 해보려고 좀 더 성장한 모습만 담으려다가 전혀 죽도 밥도 안되는 것을 알고 나의 한계성을 깨달으며, 그냥 부끄럽지만 자바스크립트 기초 부터 그동안 쪼맨씩 해왔던거 기록할려고 한다.

누가 뭐라 해도 블로그를 제일 잘보는건 나이기 때문에 ㅎㅁㅎ 나를 위해서!!

오늘은 변수의 선언과 할당을 위주로 좀 더 딥하게 파볼 예정 ( 언제나 딥함의 기준은 내 기준 )

 

나는 그래도 블로그가 좋다!!! 블로그로 정리하면서 공부하자!!!! 다시 화이팅 다지기 끌끌..

 

 

변수 선언, 할당 하기 전에 나 혼자 헷갈릴까봐 몇개 그냥 끄적이고 시이작!!!!

 

 

참고 : 노마드 코더 바닐라 JS 로 크롬 앱 만들기, 모던 자바스크립트 튜토리얼 

 

 

브라우저 내장 엔진이 어떻게 동작 ?

 

기본 원리

 

1. 브라우저 내장 엔진이 스크립트 ( 기존 엔진과도 기본 원리는 통함 . ) 를 읽음 >>> 파싱

2. 읽어 들인 스크립트를 기계어로 전환 >>> 컴파일

3. 기계어로 전환된 코드를 실행. 전환 되었기 때문에 실행 속도가 빠름.

 

엔진은 각 단계마다 최적화를 진행. 컴파일이 끝나고도 ( 2번 과정 ) 계속 현재 실행 중인 코드를 감시하면서 , 분석하고 다시 기계어를 다시 최적화하기도 함. 이런 과정을 통해 스크립트 실행 속도는 더욱 더 빨라짐.

 

이걸 적는 이유는 JSON 파일을 파싱하는 parse 코드가 있기도 하고 설명하는 거 듣다가 컴파일, 파싱이라는 용어 자체가 헷갈리기 때문.. 헣허 정말 엉망이군 쨋든 다시 정리다..!

 

 

 

자바스크립트가 끝날 때는 세미콜론 걍 무조건 붙이자.

 

대부분의 자바스크립트 문(statement) 은 줄바꿈을 함으로써 자동으로 세미콜론으로 인식하여 문을 분리한다. 

하지만 대.부.분 이니 그냥 끝날 때는 무조건 세미콜론 붙이자. 세미콜론 때문에.. 에러띄워서 고생하지 말자..

 

 

증맬 쌩기초 그냥 나혼자 다짐하면서 이제 본문으로 ㄱ

 

 

변수를 선언하고, 할당할 때 무엇을 쓰는게 좋을까?

 

이 문제의 본질적.. 본질적으로 들어가 보았다. 물론 내가 최대한 이 의미를 파악하기 위해서 깊게 자바스크립트의 원론적인 부분 까지 들어갔다고 생각한다. 하지만 코드를 짜면서 나오는 기본적인 에러나 적어도 내가 왜 let 을 쓰고, const 를 써야 하는지, var 는 왜 쓰면 안되는지 정도는 이 섹션을 보면 다시 되새김질 할 수 있을 것 같아서 적음.

 

기본적으로 암기? 를 했을 때,

 

var 는 재선언, 재할당 가능.

let 은 재선언 불가, 재할당 가능.

const 는 둘다 불가능.

 

이라고 외웠? 었다. 하지만 마냥 이렇게 텍스트로만 들으면 역시 해결되지 않지. 직접 쳐보자.

 

 

먼저 변수 선언 , 할당 

 

let korin = 'coding is difficult' ;
// 선언 부분   // 할당 부분

 

선언, 할당 이 기본적인 것 조차 일단 잡고가야 호이스팅 개념에서 안 헷갈릴 거 같아서.. 일단 이렇게 정리.

 

 

let korin;                // korin 선언.
>>> undefined             //할당된 값이 없기 때문에 undefined .
korin = 'hello world';    // korin에 'hello word' 라는 값 할당.
>>> "hello world"     

korin = 'bye world';      // 'bye world' 재할당
>>> "bye world"           // 'hello word'라는 값이 삭제되고 'bye world'으로 할당 값 변경.

let me;                   // me 라는 새로운 변수 선언.
>>> undefined            // 역시 할당은 아직 하지 않았기 때문에 undefined .  
me = korin;              // korin 의 할당 값을 me 로 복사.
>>> "bye world"   
me
>>> "bye world"          // me 에 korin의 할당 값이 복사됨.

 

이렇게 let에서는 재할당이 자유롭게 가능. 복사도 가능하다. 

 

 

하지만 

 

 

이렇게 다시 let 을 사용하여 선언자체를 다시 해버리는 재선언은 할 수 없다. 이렇게 되면 에러가 뜨게 된다.

let 은 재선언은 못하지만, 재할당이 된다는 이유를 자세하기 풀어쓴 것 ㅇㅇ!

 

 

내가 이렇게 자세히 풀어쓴 이유는 이것 때문 아래의 콘솔창을 보자.

 

 

 

물론 콘솔창에서부터 다르지만, undefinedRefrenceError 는 엄연히 다른 것이다.

 

undefined 는 에러가 아닌 선언은 했는데, 그저 할당된 값이 없어 undefined로 할당된 값이 없어요~ 라고 말해주는 것이고,

RefrenceError 는 참조 에러.

풀어쓰자면, 단순히 참조를 할 수 없다는 오류가 아니라, b 라는 변수가 정의되어 있지 않음을 뜻하는, 즉 선언조차 해주지 않았다고 여기서 에러를 띄워준것 .

아예 b 라는 변수가 선언도, 할당도 하지 않은 존재 자체가 없다!!!!  라는 뜻.

해당 오류가 생기면 오류 지점 이후로 더 이상 웹 브라우저가 코드를 실행시키지 않기 때문에, 반드시 잡아야하는 에러이다!!!

 

 

 

 

 

 

내가 이걸 왜 ..정리하느냐 나는 undefined 도 단순히 에러같은 것으로 치부해버렸기 때문에 그 생각을 뜯어 고치기 위해 이 둘의 차이를 쓴 것이다. 

 

undefined 가 났다면, 선언은 했지만 , 내가 값을 잘못 설정해주고 있거나 설정을 아예 안해준 것임 ㅇㅇ 그것을 암묵적으로 자바스크립트가 undefined 라는 값으로 할당을 해준 것이라 봐도 무방하다.

 

 

여기서 또 한 가지 짚고 넘어가야할 점.

 

null vs undefined 

 

둘 다 언뜻보면, 없는 값...? 일까..?

 

ㄴㄴ 엄격하게 따져보면 둘은 다르다고 볼 수 있다. 

 

null

은 사용자가 임의로 없는 값을 준 것이다.

 

undefined

는 값을 할당해주지 않았을 때 자바스크립트에서 자동으로 할당해준 값이다.

 

그러니 둘다 존재하지 않는 값이지만, null 은 사용자가 임의로 주어야만 발생한다.

 

 

 

아까 또 엄격하게라는 말을 굳이 추가한 이유는, 이렇게 동등연산자 == 로 둘을 나타내면 같다고 true를 반환하지만,

엄격한 일치연산자 === 를 사용하게 되면, 둘은 같지 않다는 false 를 반환한다.

 

 

 

자 근데 왜 var 를 쓰면 안좋을까? (참고 :jhyeon.log

 

 

var 는 재선언, 재할당이 가능하다. 자유로운 선언,할당 방법이다. 이것이 장점일수도 있겠지만, 이로써 나타나는 단점들이 더 많다고 할 수 있다. 

var 키워드는 생략이 가능하며, 이는 곧 전역 변수를 만들 가능성이 높아진다. 

 

내가 해당 함수, 또는 해당 블럭에만 이 변수를 사용하고 싶은데, 전역변수는 어떠한 영역에서도 참조될 수 있다. 그러니 의도치 않게 값이 변경이 될 수도 있고, 이 변수가  어디서부터 어디까지 사용될지 파악하기가 혼란스럽게 되기 때문에 개발자의 실수를 일으킬 수 있는 소지가 다분하다.

 

 

호이스팅에 대해서도 차이가 나기 때문에, 한번 봅씨다

 

 

 

 

이렇게 var 와 let 으로 선언하기 전에,  console.log 를 각각 찍어주었음.

 

 

여기서 이렇게 차이가 잘 나타나게 된다. 

var 는 선언이 되기도 이전에 참조가 되어버려서 할당값이 없다는 undefined 가 떠버리고, let 은 선언, 할당 이 되어 있지 않다는 ReferenceError 가 뜬다. 

 

( 갑자기 브라우저 콘솔로 직접 찍다가 vs code 찍은 이유는 브라우저 콘솔과, vs code 에서 코드 치고 나오는 로그 값이 미묘하게 달라서 그럼. 괜히 헷갈릴까봐 일단 이렇게 쳤음. 이거에 대해 딥하게 파려니 끝도 없어서 당장은 ...ㅎㅎ )

 

 

좀 더 극단적인 예를 들어보자.

 

 

 

예를 잘든건지는 모르겠지만... 이렇게 그냥 막 뒤섞여서 코드를 치고, korin 3을 기점으로 let을 써봤음  흐름을 잘 생각해보자.

 

결과창 ㄲ

 

 

 

위에는 전부 undefined 가 뜨고 let 에서는 korin3 이 ReferenceError 가 뜨면서, 그 밑에 있는 hello 코드는 실행 되지 않았다. 그러니

우리는 let 을 쓰면 어느 부분이 에러가 나서, 어디를 고쳐야할지 알 수 있는 반면에, var 는 전부 undefined 가 뜨게 됨. 그러니 내가 어디서 잘못 값을 할당했고, 뭘 선언했는지 그냥 간단한 선언만해도 뭐가뭔지 헷갈리는 현상이 발생한다.

 

 

 

또한 var 키워드는 생략이 가능하기 때문에, num 이 선언되지 않아도, 에러를 띄우지 않고 콘솔창에 뜨는 것이 아무것도 없기 때문에 우리가 가 만약 num 이란 변수를 쓴 줄 모르고 밑에다가 또 num을 var 로 선언해준다면, 

 

 

 

이렇게 5가 되어버림... 그러니 var 는 정말 코딩 초고수아니면 못쓸듯  난 아마 안쓸듯 ㅎㅁㅎ..

 

 

또한 var 는 범위가 함수 레벨의 스코프이다. 

나는 해당 for문 안에서만 i 를 사용하고 싶은데, 얘는 함수가 범위이므로, for문 밖에서의 함수에서도 동작한다.

 

다음 예를 봅씨당.

 

 

 

 

이렇게 i 만 var 와 let 의 차이를 두었다.

 

그러면 결과 값을 볼까나

 

 

 

undefined 는 신경쓰지 말고,  보면 var 로 설정한 i 는 전부 5가 나오는 반면에, let은 1,3 이 튀어나옴. 둘다 list에는 각각의 for문으로 돈 함수들이 담길텐데, myList[1]() 를 통해서 2번째에 있는 함수의 값을 살펴보면, 몇번째의 함수든 5가 튀어나오는 것이 보일 텐데, 이것은 i 가 for문안에서만 영향을 미치는 것이 아니라 for 문의 위에인 함수에도 영향을 미쳐서 

 

 

 

여기서 i 를 찍어보면,

 

 

이렇게 5 가 나옴. 5가 나오는 이유는 for문의 조건을 만족하는 4까지 다 돌고 나서 5부터는 for 문의 조건이 부합하지 않기 때문에 5부터는 i 가 출력이 되지 않아야 하는데,  i 가 전역변수가 되어 로그가 5라고 출력되어 나오는 것이다.

 

 

반면에 let으로 설정한 i를 찍어보자.

 

 

i는 for문 안에서만 작동하기 때문에 이렇게 let i 는 에러를 띄워준다. 

 

var 는 정말 위험하다 왜냐하면,

 

 

 

 

방금도 내가 코드치다가 어..? 했기 때문 ㅎ 여기서도 5가 두번이 나오는 이유는 위에 함수에서 설정한 i 가 밑에서도 참조가 되어 var i 가 두번 출력된 것 ...

 

그러니 정말 조심하자.

 

let, const 는 블록단위 스코프 ( 중괄호 ({}) , for,if ,while 범위 안에서만 작동. ) 이기 때문에, 좀 더 디버깅 하기 쉬워진다. 

 

 

 

 

 

해당 예를 보면 각각 {} 안 즉, 블록안에서 선언된 a,b,c 와 블록밖에 선언된 b,c 가 다르게 작동 되는 것을 볼 수 있다.

 

그리고 a는 블록안에서만 유효하기 때문에, 블록 밖에서 a 의 콘솔로그를 출력하면, 역시 에러를 띄우는 것을 볼 수 있다.

 

 

후.. 마지막으로 그럼 let 과 const 의 차이.

 

const 는 let 보다 엄격한 선언방법으로,

 

 

가장 큰 차이점은, let 은 재할당은 언제든 가능하고, 선언만 할 수 있다는 점. const 는 선언과 할당이 동시에 이루어져야 한다. ( 여기서 initializer 초기화는 처음으로 변수를 선언하고 할당하는 것을 말한다. )

 

let a = 20 ;
a=10;
console.log(a); // >>> 10
let a= 20;
console.log(a); // >>> Uncaught SyntaxError: Identifier 'a' has already been declared



const b =10;
b=30;
console.log(b); // >>> Uncaught TypeError: Assignment to constant variable.
const b = 20;
console.log(b); // >>> Uncaught SyntaxError: Identifier 'b' has already been declared

 

 

이렇게 보면 바로 비교 가능 ! let 은 재할당은 가능, 재선언은 에러. const 는 재할당, 재선언 전부 에러!!

 


 

 

후... 그러니 총정리를 해볼까....

 

 

이러한 어렵고 복잡하고 실수 투성이인 var 보다는 let 과 const 를 쓰고, 재할당이 필요하지 않은 경우는 const 로 변하지 않는 상수값을 선언,할당해놓고, 재할당이 필요하다 싶으면 나중에 let 으로 바꾸자.

 

이제 왜 다들 const 를 먼저 쓰라는지 단순히 그냥 아~ 그렇구나 가 아닌 아 ~ 이래서 안되는 구나를 뼈저리게 느낀 시간이 되었움.

 

 

 

그냥 처음부터 시작하는 마음으로 자바스크립트 변수 선언, 할당 부분 공부 완료! 하지만 여전히 파면 팔수록 자바스크립트는 더 딥하게 공부해야하는 것들이 많더라.. 최대한 줄였는데도 이만큼이니... 오늘의 포스팅 끝!

 

 

댓글