: number, string, boolean, nullm undefined와 같은 고정된 저장 공간을 차지하는 데이터를 말한다. ( 객체가 아니면서 method를 가지지 않는 타입을 말한다)
원시타입 데이터는 각 변수간의 원시타입 데이터를 복사할 경우, 데이터값이 복사되기 떄문에 만약 복사된 데이터가 바뀌더라도 기존의 데이터에 영향이 가지 않는다
ex) let a = 1;
a = b; // b=1 ->데이터 복사
b = 2; // 데이터값 바뀜
a; // 2 기존 데이터에 영향이 가지 않음
왜 원시 자료형이라고 부르는가?
원시 자료형은 모두 '하나'의 정보, 즉 데이터를 담고 있다. 옛날에는 데이터 저장소(메모리)의 용량이 제한되어 변수 하나에 데이터 용량이 제한된 하나의 원시 자료형 밖에 담을 수밖에 없었기 때문이다.
변수에는 하나의 데이터만 담는다. 값 자체에 대한 변경이 불가능(immutable)하다.
let word = "hello world!"
word = "hello codestates!" // 하지만, 변수에 재할당을 하여 변수에 담긴 내용을 변경하는 것은 가능하다. 하지만 const(상수)는 재할당은 불가능하다.
: 대량의 데이터를 다루기에 적합한 배열, 객체, 함수가 대표적이다.
ex) let e = [10, 20];
let f = e; // f = [10, 20] -> 데이터 복사
f[0] = 50; // f = [50, 20] ->데이터 변경
e; // [50, 20] -> 기존 데이터에 영향이 간다.
- 코드가 실행된 후, 콘솔에 찍히는 값은 각각 무엇인가?
console.log(3.14 === 3.14);
console.log([1,2,3] === [1,2,3]); // false -> 참조 자료형은 heap이라는 별도의 메모리 저장공간을 사용한다. 컴퓨터는 두개의 heap공간의 주소를 확보하기 떄문에 주소값을 달라서 false이다.- 코드가 실행된 후, x.foo의 값은 무엇인가?
let x = { foo: 3 };
let y = x;
y = 2 // x.foo = 3 -> y는 x의 주소값을 할당받았으나, 2를 재할당 받아 x의 참조자료형 {foo : 3}에는 아무런 영행을 미치지 않는다.- 코드가 실행된 후, score 의 값은 무엇인가?
let score = 80;
function doStuff(value) {
value = 90;
}
doStuff(score) // 80 -> 매개변수 value에 score의 값 80이 전달되고, value에는 90이 할당된다.
다만 score의 값 80은, 참조 자료형이 아니기 때문에 주소값을 전달하지 않고, 값 자체를 복사하여 전달하게된다.
그래서 함수에서 어떤 일이 발생했던가와 관련이 없이 score는 초기에 할당된 값 80이 그대로 유지된다.
: 영어 단어의 뜻은 '범위'를 의미한다. JavaScript에서의 스코프는 '변수의 유효범위'로 사용된다.
안쪽 스코프에서 바깥쪽 스코프로는 접근할 수 있지만 반대는 불가능!
스코프는 중첩이 가능하다. 가장 바깥쪽의 스코프는 전역 스코프(Global Scope)라고 부르고, 전역이 아닌 다른스코프는 전부 지역 스코프(local scope)이다.
(( 전역 스코프에서 선언한 변수는 전역변수, 지역 스코프에서 선언한 변수는 지역변수이다.))
지역 변수는 전역 변수보다 더 놓은 우선순위를 가진다.
문제 : 콘솔에 출력되는 결과는?
1. let name = '김코딩';
function showName() {
let name = '박해커'; // 지역 변수 -> 원래 재선언은 할수 없다고 알고 있었는데, 개별적인 블럭 스코프 안에서는 이름 충돌이 발생하지 않는다.
console.log(name);
}
console.log(name); // 김코딩
showName(); // 박해커 -> 지역 변수가 전역 변수보다 우선순위가 높으므로, 지역 변수 name이 출력된다. 동일한 변수 이름으로 인해 바깥쪽 변수가 안쪽 변수에 의해 가려지는(shadow) 이러한 현상을 쉐도잉(variable shadowing)이라고 부른다.
console.log(name); // 김코딩
2. let name = '김코딩';
function showName() {
name = '박해커'; // 위의 1번 문제와 다르게, let 키워드를 사용한 선언이 존재하지 않는다. 이는, '박해커'라는 값으로 할당하고 있는 name 변수는 전역에 선언된 name 변수를 그대로 사용하겠다는 의미이다.( 지역 스코프에서 새로 선언되지 않으면 그냥 같은 변수이다.)
console.log(name);
}
console.log(name); // 김코딩
showName(); // 박해커
console.log(name); // 박해커 -> showName 함수가 실행되기 전, 처음에는 '김코딩'을 출력하고, 그 이후에는 전역변수 name의 값이 바뀌기 때문에 두 번째 및 세 번째 출력에 '박해커'가 출력된다.
1. for (let i = 0; i < 5; i++)
console.log(i);
}
console.log('final i:', i); // ReferenceError ->블록 스코프 안에서 정의된 변수 i는 블록 범위를 벗어나는 즉시 접근할 수 없다.
2. 위와 달리 let대신 var 키워드를 사용
for (var i = 0; i < 5; i++)
console.log(i);
}
console.log('final i:', i); // 5 -> 어떻게 블록을 벗어났는데도 변수 i에 접근할수 있었을까?
** var 키워드는 for문이 만들어낸 블록 스코프를 무시하고, 같은 함수 스코프만 따른다. 그러나!! 화살표 함수의 블록 스코프는 무시하지 않는다.
var myName = '김코딩';
console.log(window.myName); // 김코딩
funciton foo() {
console.log('bar');
}
console.log(foo === window.foo); // true