자바스크립트에서 값은 항상 문자열이나 숫자형 같은 특정한 자료형에 속합니다.
자바스크립트에는 여덟 가지 기본 자료형이 있습니다.
자바스크립트의 변수는 자료형에 관계없이 모든 데이터일 수 있습니다. 따라서 변수는 어떤 순간에 문자열일 수 있고 다른 순간엔 숫자가 될 수도 있습니다.
이처럼 자료의 타입은 있지만 변수에 저장되는 값의 타입은 언제든지 바꿀 수 있는 언어를 ‘동적 타입(dynamically typed)’ 언어라고 부릅니다.
자바스크립트에서 행해지는 수학 연산은 '안전’하다고 볼 수 있습니다.
0으로 나눈다거나 숫자가 아닌 문자열을 숫자로 취급하는 등의 이례적인 연산이 자바스크립트에선 가능합니다.
말이 안 되는 수학 연산을 하더라도 스크립트는 치명적인 에러를 내뿜으며 죽지 않습니다.
NaN을 반환하며 연산이 종료될 뿐입니다.
==는 a == b 라고 할때, a와 b의 값이 같은지를 비교해서, 같으면 true, 다르면 false라고 한다.(값만 같으면 true이다.)
===는 Strict, 즉 엄격한 Equal Operator로써, "엄격하게" 같음을 비교할 때 사용하는 연산자이다.
===는 a === b 라고 할때, 값과 값의 종류(Data Type)가 모두 같은지를 비교해서, 같으면 true, 다르면 false라고 한다.
출처 : https://enfanthoon.tistory.com/171
자바스크립트에서는 Request를 넘기면서 따로 타입을 체크하지 않기 때문에, 서버 단에 요청할 때 까지도 이 Request는 에러가 뜰 것이라는 것을 감지하지 못합니다.
undefined는 ‘아무 값도 할당받지 않은 상태’를 의미한다.
var 키워드로 선언한 변수는 암묵적으로 undefined로 초기화된다.
변수 선언에 의해 확보된 메모리 공간을 처음 할당이 이뤄질 때까지 빈 상태(*대부분 비어 있지 않고 쓰레기 값이 들어 있다.)로 내버려두지 않고 자바스크립트 엔진이 undefined로 초기화한다.
따라서 변수를 선언한 이후 값을 할당하지 않은 변수를 참조하면 undefined가 반환된다.
변수를 참조했을 때 undefined가 반환된다면 선언 이후 값이 할당되지 않은 즉, 초기화되지 않은 변수라는 것을 알 수 있다.
undefined는 개발자가 의도적으로 할당하기 위한 값이 아니라 자바스크립트 엔진이 변수를 초기화 할 때 사용하는 값이다.
자바스크립트 엔진이 변수를 초기화라는 데 사용하는 undefined를 개발자가 의도적으로 변수에 할당한다면 undefined의 본래의 취지와 어긋나고 또한 혼란을 야기하므로 권장하지 않는다.
그렇다면 변수에 값이 없다는 것을 명시하고 싶을 때는 어떻게하면 좋을까? 바로 undefined를 할당하는 것이 아니라 null을 할당한다.
자바스크립트는 대소문자를 구분하므로 null은 Null, NULL 등과는 다르다.
null은 ‘비어있는, 존재하지 않는 값'(값의 부재)을 의미한다.
프로그래밍 언어에서 null은 변수에 값이 없다는 것을 의도적으로 명시(의도적 부재)할 때 사용한다.
변수에 null을 할당하는 것은 변수가 이전에 참조하던 값을 더 이상 참조하지 않겠다는 의미이다.
이는 이전에 할당되어 있던 값에 대한 참조를 명시적으로 제거하는 것을 의미하며, 자바스크립트 엔진은 누구도 참조하지 않은 메모리 공간에 대해 *가비지 콜렉션을 수행할 것이다.
*가비지 콜렉션
가비지 컬렉션은 프로그램에서 더 이상 사용하지 않는 메모리를 자동으로 정리하는 것이다.
비워줘야 할 메모리 공간을 남겨두지 않고 메모리를 꽉채우게 되면, 메모리 누수(memory leak)가 발생한다.
메모리 누수로 속도저하, 예기치 못한 종료, 느린 응답속도 등과 같이 많은 문제가 발생할 수 있다.
메모리 누수가 발생하지 않게 프로그래머는 이를 방지하고 버그가 있으면 잡아야한다.
가비지 컬렉터는 프로그래밍 언어에서 프로그래머가 해야할 위와 같은 일을 대신해준다.
메모리를 알아서 관리하는 언어들을 managed language라고 한다. (반대: unmanaged language)
특정 때에 특정 방식으로 필요없는 정보들 즉, 가비지들을 쓸어담아 버린다.
단, 지워야할 것들을 100 퍼센트 잡아내지는 못한다.
좋은 프로그래머가 되려면 메모리 관리에도 신경을 써야 한다.
먼저 불변(immutability)이란 뭘까? 단어에서 유추해볼 수 있다시피 '변하지 않는' 뜻이라고 생각하면 되겠다.
그럼 '불변 객체'란? '변하지 않는 객체' 즉 이미 할당된 객체가 변하지 않는다는 뜻을 가지고 있다.
자바스크립트에서 불변 객체를 만들 수 있는 방법은 기본적으로 2가지 인데 const와 Object.freeze()를 사용하는 것이다.
const는 할당된 값이 상수가 되는 것이 아닌 바인딩된 값이 상수가 되는, 즉 test변수가 상수가 되기 때문에 const 키워드로 선언된 test변수에는 객체 재할당은 불가능하지만 객체의 속성은 변경 가능하다.
Object.freeze()는 동결된 객체를 반환하지만 객체의 재할당은 가능하다.
그럼 결국 불변 객체는 어떻게 만들 수 있냐면..
const와 Object.freeze()를 조합하여 만들 수 있다. (const의 재할당불가 + Object.freeze()의 객체속성 변경불가)
결론부터 말하자면 얕은 복사는 객체의 참조값(주소 값)을 복사하고, 깊은 복사는 객체의 실제 값을 복사합니다. 먼저, 자바스크립트에서 값은 원시값과 참조값 두 가지 데이터 타입의 값이 존재합니다.
원시값은 기본 자료형(단순한 데이터)을 의미합니다. Number, String, Boolean, Null, Undefined 등이 해당합니다. 변수에 원시값을 저장하면 변수의 메모리 공간에 실제 데이터 값이 저장됩니다. 할당된 변수를 조작하려고 하면 저장된 실제 값이 조작됩니다.
참조값은 여러 자료형으로 구성되는 메모리에 저장된 객체입니다. Object, Symbol 등이 해당합니다. 변수에 객체를 저장하면 독립적인 메모리 공간에 값을 저장하고, 변수에 저장된 메모리 공간의 참조(위치 값)를 저장하게 됩니다. 그래서 할당된 변수를 조작하는 것은 사실 객체 자체를 조작하는 것이 아닌, 해당 객체의 참조를 조작하는 것입니다.
함수 안에 있는 선언들을 모두 끌어올려서 해당 함수 유효 범위의 최상단에 선언하는 것을 말한다.
자바스크립트 함수는 실행되기 전에 함수 안에 필요한 변수값들을 모두 모아서 유효 범위의 최상단에 선언한다.
자바스크립트 Parser가 함수 실행 전 해당 함수를 한 번 훑는다.
함수 안에 존재하는 변수/함수선언에 대한 정보를 기억하고 있다가 실행시킨다.
유효 범위: 함수 블록 {} 안에서 유효
즉, 함수 내에서 아래쪽에 존재하는 내용 중 필요한 값들을 끌어올리는 것이다.
실제로 코드가 끌어올려지는 건 아니며, 자바스크립트 Parser 내부적으로 끌어올려서 처리하는 것이다.
실제 메모리에서는 변화가 없다.
호이스팅의 대상
var 변수 선언과 함수선언문에서만 호이스팅이 일어난다.
var 변수/함수의 선언만 위로 끌어 올려지며, 할당은 끌어 올려지지 않는다.
호이스팅이란 스코프 내부 어디서든 변수 선언은 최상위에 선언된 것처럼 행동하는 것을 의미한다.
그런데 var 키워드처럼 동작하지 않고 에러가 발생되는 걸까? 바로. Temporal Dead Zone(TDZ)라는 것 때문에 일어난다.
TDZ 영역에 있는 변수들은 사용 가능하지 않는데, 바로 let과 const는 TDZ에 영향을 받기 때문이다. 이말은 곧 할당을 하기 전에는 사용할 수 없다는 말과 같으나 이는 코드를 예측가능하게 하고 잠재적은 버그를 줄일 수 있다는 장점을 갖는다.
TDZ(Temporal Dead Zone)란, 변수가 스코프의 시작 지점부터 초기화가 시작되는 지점까지의 구간을 말한다.
let과 const키워드는 var키워드처럼 호이스팅(hoisting)이 일어난다.
```jsx
let b = 1;
function hi () {
const a = 1;
let b = 100;
b++;
console.log(a,b); <-- second
}
//console.log(a); <-- 함수 안으로 옮기면 오류가 안남
console.log(b); <- first
hi();
console.log(b);
---------------------------------------------------------------------------
위를 콘솔로 찍으면 1 // 1 101 // 1
이렇게 뜰 것이다. 맨처음 1은 first 두 번째의 1 101 은 second 그리고 마지막 1이다.
function 안에서 b 는 100이며 b++까지 했으니 101이지만, 이는 함수 안에서만의 b이다.
처음에 b를 1로 설정했기 때문에 , hi();를 하면 함수 안의 console.log(a,b)가 작동하면서 b가 101이라는 값이 나온다.
여기서 hi();를 없앤다면 콘솔은 1 // 1 만 찍힐 것이다.
주석 처리된 console.log(a)는 함수 안으로 옮기면 1 이라는 값을 도출한다
```
출처 : https://ko.javascript.info/types