[객체와 Map의 차이점 💡] 1) 객체는 주로 문자열을 key로 사용하고, 순서가 보장되지 않음. (비록 ES6 이후 객체는 키의 순서를 어느 정도 보장하지만 Map보다는 덜 신뢰할 수 있음) 2) Map은 임의의 자료형을 key로 사용 가능하고, 항상 순서를 보장하며, 성능이 더 뛰어날 때가 많음.
var, let, const는 크게 변수의 범위(스코프) / 중복 선언 / 호이스팅으로 구분하여 비교할 수 있다.
변수의 범위로 보는 차이점
1. var는 함수 스코프(function scope)를 가지는 변수이다. 즉, 변수를 선언한 함수 내에서만 유효하고, 함수 밖에서는 접근할 수 없다.
함수 바깥에서 선언하면 전역 변수(global variable)로 취급된다.
* 함수 스코프에서만 가지므로 if문이나 for문 등에서는 적용이 되지 않는다.
functionsayHi () {
var say = 'Hi';
console.log(say); // Hi 출력
}
console.log(say); // Error 발생
if(true) {
var title = 'JavaScript';
console.log(title); // JavaScript 출력
}
console.log(title); // JavaScript 출력
for(var i = 1; i < 4; i++;) {
console.log(i); // 1부터 3까지 출력
}
console.log(i); // 4 출력
2. let, const은 블록 스코프(block scope)를 가지므로, 변수를 선언한 {} 안에서만 유효하고, 그 밖에서는 접근할 수 없다.
functionsayHi () {
let say = 'Hi';
console.log(say); // Hi 출력
}
console.log(say); // Error 발생
if(true) {
const title = 'JavaScript';
console.log(title); // JavaScript 출력
}
console.log(title); // Error 발생
for(let i = 1; i < 4; i++;) {
console.log(i); // 1부터 3까지 출력
}
console.log(i); // Error 발생
중복 선언
1. var는 같은 이름으로 선언된 변수를 다시 선언할 수 있다.
중복 선언 시에는 나중에 선언된 값으로 덮어씌워진다.
var title = 'JavaScript';
console.log(title); // JavaScript 출력
var title = 'HTML';
console.log(title); // HTML 출력
title = 'CSS';
console.log(title); // CSS 출력
2. let는 같은 스코프 내에서 같은 이름의 변수는 다시 선언할 수 없다.
let title = 'JavaScript';
console.log(title); // JavaScript 출력
let title = 'HTML';
console.log(title); // Syntax Error
title = 'CSS';
console.log(title); // CSS 출력
3. const도 같은 스코프 내에서 같은 이름의 변수는 다시 선언할 수 없다.
또한, 선언 후 재할당이 불가능하고, 한번 값이 할당되면 그 값을 변경할 수 없다.
하지만 객체나 배열 같은 참조형 데이터의 경우, 객체의 속성이나 배열의 요소를 변경할 수 있다.
const title = 'JavaScript';
console.log(title); // JavaScript 출력
const title = 'CSS' // Syntax Error
title = 'HTML'; // Type Error
const obj = { name: 'Alice' };
obj.name = 'Bob'; // 가능
호이스팅(Hoisting)
[호이스팅이란? 🔍]
호이스팅은 자바스크립트의 변수 선언과 함수 선언이 코드 실행 전에 끌어올려지는 현상이다.
자바스크립트는 코드를 실행하기 전에 선언을 먼저 처리하고, 그 다음에 실제 코드 실행을 처리한다는 특징이 있다.
하지만 호이스팅이 어떻게 작동하는지에 따라 다르게 동작할 수 있다.
1. var로 선언된 변수는 선언만 호이스팅되고 초기화는 되지 않는다.
즉, 변수가 함수의 제일 위로 끌어올려지지만 값은 할당되지 않은 상태로 올라간다.
console.log(title); // undefined 출력
var title = 'This is title';
2. let, const으로 선언된 변수도 호이스팅이 일어나지만, 변수 선언 전에 접근하면 ReferenceError가 발생한다.
초기화 전까지는 Temporal Dead Zone (TDZ)에 있기 때문에 값을 참조할 수 없다.
console.log(title); // Reference Error
console.log(name); // Reference Error
let title = 'This is title';
const name = 'My name is name';
.js는 자바스크립트의 파일 확장자이며 일반적으로 사용하는 순수 자바스크립트 코드가 들어간다.
브라우저가 이해할 수 있는 코드이고, 리액트를 쓰지 않아도 문제 없는 파일 형식이다.
[예시 코드]
function sayHello(name) {
console.log("Hello, " + name);
}
sayHello("John");
.jsx 란?
.jsx는 JavaScript XML의 약자이며 자바스크립트 코드 안에 HTML과 비슷한 문법을 쓸 수 있게 해주는 확장자이다.
주로 React에서 사용되며, JSX 문법을 사용하면 마치 HTML처럼 UI를 구성할 수 있다.
하지만 브라우저는 JSX를 이해하지 못하므로 컴파일 변환이 필요하다.
* .js에서도 JSX 문법을 사용할 수는 있음!
[개념 알고가기 💡] 1. XML(eXtensible Markup Language)이란? 확장 가능한 마크업 언어로, HTML처럼 태그로 데이터를 표현하지만 HTML보다 훨씬 더 유연하고 데이터 중심적이다. 원래는 데이터 저장/전송용 포맷으로 만들어졌으며, 특징은 다음과 같다. 1) 사용자가 직접 태그를 정의 가능 2) 구조적 데이터 표현에 적합 3) 사람도 읽기 쉽고, 기계도 파싱하기 쉬움 * 단순히 데이터를 표현하는 방법이며, 실제 동작은 하지않고 데이터를 설명하는 "형식"이다.
* 따라서 JSX는 JavaScript XML이란 이름이지만, 실제로는 XML이 아니고XML처럼 생긴 문법을자바스크립트에 끼워 넣은 것이다.
라면으로 예시를 들어보자면, 라면을 먹기 위해 물을 끓이기 시작하고, 물이 다 끓으면 면을 넣고 끓인 뒤 라면을 먹는다.
코드로 표현하자면 다음과 같다.
functionboilWater() {
console.log('1. 물 끓이기 시작');
for (let i = 0; i < 3; i++) {
console.log('2. 물 끓이는 중 ...');
}
console.log('3. 물을 다 끓였어요!');
}
functionmakeRamen() {
boilWater();
console.log('4. 면 넣고 끓이기');
console.log('5. 라면 완성!');
}
makeRamen();
코드의 흐름을 보면, makeRamen이 호출되면서 먼저 boilWater 함수가 실행된다.
boilWater 함수에서 1번이 출력된 후, 2번이 3번 출력되고 나서 3번이 출력된다.
이 과정이 끝날 때까지 다음 코드는 실행되지 않으며, 작업이 끝나면 함수를 빠져나와 그 이후의 작업인 4번과 5번이 순서대로 출력된다.
// 출력
1. 물 끓이기 시작
2. 물 끓이는 중 ...
2. 물 끓이는 중 ...
2. 물 끓이는 중 ...
3. 물을 다 끓였어요!
4. 면 넣고 끓이기
5. 라면 완성!
그렇다면 비동기에서의 라면은 어떻게 끓일까?
비동기란(Asynchronous)? : 일이 끝나길 기다리지 않고 다른 일을 먼저 처리하는 방식
일단 라면을 먹기 위해 물을 끓일 것이다.
하지만 이전과 다른 점은, 라면을 끓일동안 게임을 하다 올 것이다.
게임을 하다가 물이 끓으면 타이머가 울리고, 그때 면을 넣고 끓인 후 라면을 먹으면 된다.
코드로 표현하자면 다음과 같다.
functionboilWaterAsync() {
console.log("1. 물 끓이기 시작");
setTimeout(() => {
console.log("3. 물 끓었음");
console.log("4. 면 넣고 끓이기");
console.log("5. 라면 완성!");
}, 3000);
}
functiondoSomethingElse() {
console.log("2. 게임하기 🎮");
}
boilWaterAsync();
doSomethingElse();
먼저 boilWaterAsync가 호출되고 1번이 출력된다.
그 후 setTimeout으로 3초 뒤 실행하게끔 3, 4, 5번이 출력되게끔하고,
그 사이에 doSomethingElse가 호출되면서 2번이 출력된다.
그리고 3초 후 3, 4, 5번이 순서대로 출력된다.
1. 물 끓이기 시작
2. 게임하기
(3초 후 ...)
3. 물 끓었음
4. 면 넣고 끓이기
5. 라면 완성!
그럼 이제 비동기에서 중요한 개념들인 콜백, Promise, async/await은 뭘까?
콜백 함수란? : 콜백은 “나중에 실행할 함수”를 인자로 전달해서, 어떤 일이 끝난 뒤 실행되게 하는 방식