⇒ string, number, bigint, boolean, undefined, symbol, null
⇒ 원시 자료형은 값 자체에 대한 변경이 불가능(immutable)하지만, 변수에 다른 데이터를 할당할 수는 있음.
⇒ 원시 자료형을 할당하는 경우, 그 값 자체를 변수에 할당함. (그 값을 복사해서 변수에 저장)
let x = 2;
let y = x;
y = 3;
//여기서 x는 여전히 2임.
//x의 값을 y로 복사해서 할당했기 때문에 세번째 줄 코드가 변수 x에 영향 미치지 않음.
let score = 80;
function doStuff(value){
value = 90;
}
doStuff(score)
//매개변수 value에 score의 값 80이 전달되고,
//value = 90에서 value에 90이 재할당 됨.
// 변수 score의 값 80은 참조 자료형이 아니기 때문에 값 자체를 복사해서 전달.
// 함수에서 어떤 일이 발생했던가와 관련 없이 score 초기 할당 값 80 그대로 유지됨.
⇒ function, array, object
⇒ 참조 자료형을 변수에 할당할 때는 값이 아닌 주소를 저장하고, 데이터를 보관하는 heap이라는 특별한 데이터 보관함은 동적으로 변한다.
⇒ 참조 자료형의 ===(strict equality)는 주소값이 같은지 확인하므로, 같아 보이는 두 참조 자료형의 주소값이 다르다면 false값이 나옴.
console.log([1,2,3] === [1,2,3]); //false
console.log({foo:'bar'} === {foo:'bar'})//false
let x = { foo: 3 };
let y = x;
y.foo = 2;// 변수 x의 값의 주소가 y에 할당되고, 같은 주소를 바라보고 있는 y.foo가 2로 변경되었으므로
//같은 곳을 바라보고 있었던 x.foo도 2가 되어야 함.
스코프는 변수가 유효한 범위를 말한다.
중괄호나 함수의 안쪽에 변수가 선언 되었는가, 바깥에 선언 되었는가에 따라 변수를 사용할 수 있는지가 결정된다.
왜냐하면
- 바깥쪽 스코프에서 선언한 변수는 안쪽 스코프에서 사용가능함.그러나 안쪽 스코프에서 선언한 변수를 바깥 스코프에서 사용할 수는 없다.
- 가장 바깥쪽 스코프는 전역 스코프, 그 외는 지역 스코프라고 부르는데, 전역 스코프 내의 변수는 전역 변수, 지역 스코프의 변수는 지역 변수라고 한다.
- 지역 변수가 전역 변수보다 우선한다.
이런 규칙들이 있기 때문!
스코프의 종류는 중괄호로 나뉘는 블록 스코프, 함수로 나뉘는 함수 스코프가 있다.
블록 스코프 : 중괄호 기준으로 범위 구분. 블록 스코프 내 정의된 변수는 블록 범위 벗어나는 즉시 접근 불가.
함수 스코프 : function 키워드가 등장하는 함수 선언식 및 함수 표현식이 함수 스코프를 만듦.
(화살표 함수는 블록 스코프로 취급!!!!!!!)
변수를 선언할 때 사용하는 var, let, const 키워드들과 스코프들도 관련이 있는데,
- var 키워드는 for문이 만들어 낸 블록 스코프를 무시한다. (let 키워드 사용 권장됨)
- let 키워드(재선언 불가), const 키워드(재할당, 재선언 불가)는 블록/함수 스코프 모두 유효.
브라우저에만 존재하는 객체로 브라우저 창을 대표하며, 전역 영역을 담고 있다.
함수 선언식으로 함수를 선언하거나, var로 전역 변수를 만들면, window에서도 동일한 값 찾을 수 있음.
var myName = '나나';
console.log(window.myName); //나나
function foo() {
console.log('love');
}
console.log(foo === window.foo);//true
why??
의도하지 않은 변경 = side effect를 줄일 수 있다.
전역 변수를 var로 선언하는 경우, var로 선언한 전역 변수가 window 기능을 덮어씌워 내장 기능을 사용할 수 없게 만들 수 있다.
예를 들어 var로 전역 변수 console을 선언하면 window 내장 기능인 console.log를 사용할 수 없다.
why?
선언 없이 변수 할당 시, 해당 변수는 var로 선언한 전역 변수처럼 취급된다.
=> strict mode를 사용하면 문법적으로 실수할 수 있는 부분들도 에러로 판단하여, 선언 없는 변수 할당 등도 에러로 판단 가능. (js 파일 상단에 'use strict'라고 입력)
동일한 변수 이름으로 인해 바깥쪽 변수가 안쪽 변수에 의해 가려지는 현상.
let name = "까치";
function showname(){
let name = "삼순";
console.log(name);
}
showname()//바깥쪽 name에 할당된 "까치"가 아니라, 함수 내부의 "삼순"이 출력됨.