let num = 1;
num = num * 3;
let str = '문자';
str = '다른 문자';
let arr = [];
arr = [1,2,3];
let obj = {};
obj = { name: '새 객체'};
const로 선언한 변수는 값을 다시 할당할수 없는것이지 값을 변경할 수는 있습니다.
예?
const num = 1;
num = 3; //자료형 오류 발생
const str = '문자';
str = '새 문자'; //자료형 오류 발생
const arr = [];
arr = [1,2,3]; //자료형 오류 발생
const obj = {};
obj = {name: '내 이름'}; //자료형 오류 발생
constr arr2 = [];
arr2.push(1); // arr2 = [1]
arr2.splice(0,0,0); // arr2 = [0,1]
arr2.pop(); // arr2 = [1]
const obj2 = {};
obj2['name'] = '내이름'; // obj2 = {name: '내이름'}
Object.assign(obj2, {name: '새이름'}); // obj2 = {name: '새이름'}
delete obj2.name; // obj2 = {}
아.. 선언은 안되지만 내장함수를 이용해서 내부 요소를 추가하거나 삭제할수 있구나.. 라는 생각이 든다.
책에서는 불변 변수는 값을 수정할 수 없다. 이런 것을 '결성 제약 조무건에 위배되었다'라고 표현한다. 그래서 불변 변수로 정의된 배열인 객체를 내장 함수로 수정하는 것을 암묵적으로 금지하여 무결성을 유지한다.
아니 근데 프로젝트 하다보면 불변함수도 수정할 때가 있을텐데..
이럴때는 수정할 불변 변수를 새로 만들어 새값을 할당하는 방법으로 수정해야한다고 한다.
정확히 말하면 수정이라기보다는 새로 정의한다는 개념에 가깝다.
예를 들면
const num1 = 1;
const num2 = num1 * 3; //num2 = 3
아니 그냥 var 쓰면 안되나...
여기서 궁금했다. var, let, const의 차이점은 뭔가 도대체.. 그래서 찾아보았다.
var은 함수 레벨 스코프 let, const는 블록 레벨 스코프를 갖는다.
이게 뭔소리야.. 그래서 또 찾아봤다.
일단 스코프는 코드에서 {}를 의미한다. 또한, 함수 스코프와 블록 스코프는 둘다 지역 스코프다. 자바로 생각한다면 지역변수란 소리다. 메서드내에 존재하는 변수.
이걸 코드로 이해해보기 위해서 다음과 같이 표현해보았다.
if(true) {
var x = 5;
}
console.log(x);
변수 x는 블록 내에 선언되었다. 에러가 날까?
여기서 x는 전역변수다. 왜? {}안에서 선언되었지만 함수가 아니다. 기본적으로 자바스크립트는 블록 레벨 스코프를 사용하지 않는다고 한다. 따라서 함수 밖에서 선언된 변수는 모두 전역 스코프를 갖게 된다.
반대로
if(true) {
const x = 5;
}
console.log(x);
그렇다 에러가 난다. 왜? ES6에서 생긴 let과 const는 블록 레벨 스코프를 갖게 되면서 스코프 내에서 선언된 변수는 블록 외에서 유효하지 않는다.
var는 사용되는 순간 변수 호이스팅이 일어난다. 초기화 하지 않아도 undefined라는 값으로 초기화가 된다. 그러면 let과 const는 호이스팅이 일어나지 않는가?
아니다. 선언 키워드들은 전부 호이스팅이 된다. 하지만 const는 선언시 초기화 하지 않으면 에러가 나고 let은 초기화 하지 않으면 초기값이 없다.
예를 들어보자.
var n = 1;
function test() {
console.log(n);
var n = 2;
console.log(n);
}
test();
//결과 :
undefined
2
왜 이러는걸까? 이 표현은 이렇게 표현될 수 있다.
var n = 1;
function test() {
var n;
console.log(n)
n = 2;
console.log(n);
}
test();
위에서 언급한 함수 스코프와 호이스팅으로 인해 var n이 함수 레벨 최상단으로 끌어올려졌다.
이러한 점 때문에 var는 전반적으로 코드가 어떻게 작동될지 직관적으로 보기 힘들다는 단점이 있고, 초기화 하지 않아도 메모리를 잡아먹기 때문에 메모리 누수를 고려하여 사용하지 않는다고 한다.