Python기반 백엔드 과정을 배우고 있지만 프로젝트를 하면서 필수적으로 프론트엔드를 구현해야 하기 때문에 자바스크립트를 다루게 됐다. 기초가 없는 상태에서 필요한 자바스크립트 코드들을 구글링한 뒤 머리 깨져 가면서 커스텀하는 건 굉장히 비효율적이다. 그래서 자바스크립트를 기초부터 차근차근 공부해 볼 생각이다. 이 카테고리는 python 등 기본적인 프로그래밍 언어를 알고 있다는 가정 하에 (나한테) 필요한 부분만 정리해서 올릴 예정이다.
00. What is JavaScript?
넷스케이프에서 일하던 브랜든 아이크가 10일만에 설계해 첫번째 버전을 만든 언어인 자바스크립트는 이것저것 허점이 많고 불편해서 당시에는 묻힐 뻔하다가 지속적인 보완과 Ajax, jQuery의 등장으로 지금은 웹개발을 하는데 없어서는 안 될 언어가 되었다. 10일만에 만들었다고 하지만 브랜든 아이크는 넷스케이프에 입사하기 전에 자신만의 언어를 개발하고 싶어서 이미 언어를 개발해 본 경험이 있는 사람이었다고 한다. 자세한 내용은 브랜든 아이크가 직접 전해주는 자바스크립트의 역사를 참조.
한편 비영리 국제 표준화 기구 ECMA International는 어떤 범용 스크립트 언어를 만들 때 준수해야 할 규칙이나 세부적인 사항들을 ECMA-262이라는 문서로 관리하고 이 범용 스크립트 언어를 ECMAScript라고 이름을 붙였다. 자바스크립트는 이 ECMAScript 기준을 따르는 언어이다. 1997년 ECMAScript 1를 줄인 ES1부터 2015년 자바스크립트의 혁명을 일으킨 ES6(ES2015), 그 이후로는 매년 새로운 개정안을 발표해 2023년 6월 현재는 ES2022까지 나온 상태다.
ES6의 주요 특징으로는 let, const 키워드, arrow function(=>), for...of문, Spread Operator 등이 있다.
01. 기본 문법
1. 세미콜론 (Semicolon)
자바스크립트는 C, C++, Java등의 언어와 같이 문장(statements)끝에 ;(세미콜론)을 붙인다. 컴퓨터에게 '여기까지가 한 문장입니다'를 구분해주기 위함이다. 물론 자바스크립트는 매우 관대하므로 한줄에 한 문장씩 작성하면 세미콜론 없이도 오류를 발생시키지 않지만, 습관적으로 문장 끝에 세미콜론을 쓰거나 formatter를 적극적으로 활용하도록 하자.
// 1
let a = 5; let b = 10;
// 2
let a = 5 let b = 10
// 3
let a = 5
let b = 10
// 1
not error
// 2
Uncaught SyntaxError
// 3
not error
2. 주석 (Comment)
// 주석1
/* 주석2 */
/**
*주
*석
*3
*/
3. 자료형 (Data Type)
자바스크립트에는 8가지 데이터 타입이 있다
1. Number - 숫자형
2. String - 문자열
3. Boolean - 불린형
4. undefined - 변수를 선언한 후 값을 할당하지 않은 상태
5. null - 빈값(빈 객체) (의도적으로 비어있음을 표현하는 값)
6. Object - 객체
7. Symbol - 변경이 불가능한 유일한 값(ES6+)
8. BigInt - Number자료형의 최대값인 2^53 - 1이상의 값을 나타낼 수 있는 객체
4. 변수 (Variable)
자바스크립트의 변수에는 기존의 var와 함께 ES6에서 새롭게 추가된 let, const가 있다. 자바스크립트에서 let과 const를 이용해 코드를 짤 것을 권장하고 있지만 ES6 이전에 var로 작성된 코드들이 구글링할 때 나올 수 있으니 알고 있어야 한다. 그럼 왜 var를 버리고 let과 const를 쓰라고 권장할까.
중복 선언 문제
기존 var로 선언한 변수의 첫번째 문제는 중복 선언이 가능하다는 점이다. 즉 변수를 덮어쓸 수 있다. 변수가 중복 선언이 될 경우 코드가 길어지면 어느 줄에서 기존에 있던 변수가 바뀌었는지 알기 힘들고 오류를 발생시킬 가능성이 있으므로 가급적 let, const로 대체해서 쓰도록 한다.
// 1
var americanoPrice = 3000;
console.log(americanoPrice);
var americanoPrice = 5000;
console.log(americanoPrice);
// 2
let cafeLatte = 3500;
console.log(cafeLatte);
let cafeLatte = 5500;
console.log(cafeLatte);
// 3
const cafeMocha = 4000;
console.log(cafeMocha);
const cafeMocha = 6000;
console.log(cafeMocha);
// 1
3000
5000
// 2
Uncaught SyntaxError: Identifier 'cafeLatte' has already been declared
// 3
Uncaught SyntaxError: Identifier 'cafeMocha' has already been declared
// 1
같은 이름의 변수를 var 키워드로 다시 할당해도 아무런 문제없이 작동한다.
// 2, 3
let, const 키워드로 변수를 선언한 뒤 다시 재할당하면 이미 cafeLatte 식별자가 선언되었다고 문법오류를 발생시킨다.
함수 스코프 문제
var 키워드로 선언한 변수는 함수 즉 function 안에서만 지역변수가 된다. 다시 말하면 if, for, while, switch문 등의 키워드 안에서 var 키워드로 변수를 선언할 경우 함수 밖에서도 호출이 가능한 전역변수가 된다.
// 1
if (true) {
var a = 1;
}
console.log(a);
// 2
if (true) {
let b = 1;
}
console.log(b);
// 1
1
// 2
Uncaught ReferenceError: b is not defined
// 1
var로 선언한 변수 a는 if문 안에서 선언했음에도 불구하고 if문 밖에서 a를 호출해도 1이란 값이 잘 출력됐다.
// 2
let으로 선언한 변수 b는 if문 안에서 선언했으므로 if문 밖에서 호출했을 때 변수 b가 정의되어 있지 않다는 오류가 출력됐다.
호이스팅(Hoisting)
var로 선언한 변수는 선언되기 이전에 접근하는 것도 가능하다.
// 1
console.log(c);
var c = 5;
// 2
console.log(d);
let d;
// 1
undefined
// 2
Uncaught ReferenceError: Cannot access 'd' before initialization
// 1
c가 선언되기 전에 console.log()로 출력했는데도 오류가 발생하지 않고 undefined가 출력됐다. 변수 선언이 끌려 올라가서 동작하는 것을 호이스팅이라고 한다.
// 2
let으로 선언된 변수는 console.log()로 출력해도 에러가 출력된다.
5. 함수(function)
자바스크립트에서 함수는 다양한 방식으로 호출할 수 있다.
- 함수 선언 (Function Declaration, 기본형)
function 함수이름(parameter1, parameter2) {
구문;
}
함수이름(argument1, argument2);
기본적으로 함수는 위와 같은 구성으로 만들고 호출할 수 있다. argument를 미입력해 parameter에 인수를 전달하지 않으면 그 값은 undefined가 된다. 그럴 경우를 대비해 기본값을 설정할 수 있다. 아래와 같다.
function 함수이름(parameter1, parameter2 = '기본값') {
구문;
}
함수이름(argument1);
이렇게 기본값을 설정해주면 argument1은 parameter1의 인수로 전달되고 parameter2에는 undefined대신 '기본값'이 인수로 전달된다.
기본값을 설정하는 또 다른 방식은 함수 내에서 undefined값이 전달됐을 경우의 값을 정해주는 것이다. 아래를 보자.
// 1
function showMessage(text) {
if (text === undefined) {
text = '기본값';
}
alert(text);
}
showMessage();
// 2
function showMessage(text) {
text = text || '기본값';
alert(text);
}
showMessage();
// 3
function showMessage(text) {
alert(text ?? "기본값");
}
showMessage();
showMessage(null);
// 1
alert알림창 : 기본값
// 2
alert알림창 : 기본값
// 3
alert알림창 : 기본값
alert알림창 : 기본값
위 케이스들은 전부 '기본값'을 출력한다.
// 1
함수 안에서 text 파라미터의 값이 undefined일 경우 text 변수에 '기본값'을 할당해주었다.
// 2
자바스크립트의 논리 연산자 &&와 ||는 조금 특이한 방식으로 동작한다.
A || B일 경우 왼쪽 A 값이 true값이라면 A값을 출력하고 false라면 B를 출력한다.
위의 경우 text = text || '기본값'; 에서 text에 undefined가 전달됐고 자바스크립트에서 undefined의 불린값은 false로 해석되므로 오른쪽의 '기본값'을 text변수에 할당했다.
더 자세한 내용은 나중에 다뤄보도록 하겠다.
// 3
ES6에서 추가된 병합 연산자를 이용한 방법이다.
A ?? B에서 A가 undefined나 null이 아니면 A값을 출력하고 아니면 B값을 출력한다.
위의 경우 A에 각각 undefined와 null이 파라미터에 전달되었으므로 둘다 B값인 '기본값'을 출력했다.
- 함수 표현식(Function Expression)
함수를 마치 값처럼 사용하는 방식. 함수를 변수에 할당하거나 또 다른 함수의 파라미터로 전달하거나 할 수 있다.
// 1
const pntKimchi = function () {
console.log('Kimchi');
};
pntKimchi();
// 2
function kimchi(func) {
func();
}
kimchi(() => {
console.log("kimchi");
});
// 1
Kimchi
// 2
kimchi
// 1
코드를 보면 console.log()로 Kimchi를 출력하는 익명함수를 변수 pntKimchi에 할당했다. 마치 함수가 변수의 값처럼 들어가는 형태로 쓰이고 pntKimchi()로 출력해도 아무 문제없이 동작한다.
// 2
kimchi()함수의 argument에 console.log()로 kimchi를 출력하는 익명함수가 마치 값처럼 전달돼 kimchi함수의 func 파라미터로 전달됐다. 익명함수는 ES6에서 추가된 Arrow function(=>)로 만들어졌다. 출력도 아무 문제없이 동작한다.
함수 선언으로 만든 함수와 함수 표현식으로 만든 함수의 중요한 차이점이 있다. 함수 선언으로 만든 함수는 사실 함수를 선언하기 전에 출력해도 아무 문제없이 동작한다. 변수 파트에서 설명했던 호이스팅이 발생하기 때문이다. 하지만 함수 표현식으로 만든 함수는 함수를 선언하기 전에 출력하려고 하면 에러가 발생한다.
// 1
printS();
var printS = function () {
console.log("JavaScript");
};
// 2
printV();
function printV() {
console.log("JavaScript");
}
// 1
Uncaught TypeError: printS is not a function
// 2
JavaScript
'프로그래밍 > Frontend' 카테고리의 다른 글
[TypeScript] Type + JavaScript - (2) Interface (0) | 2024.07.27 |
---|---|
[TypeScript] Type + JavaScript - (1) 기본 타입 (0) | 2024.07.22 |
[CSS] 03. CSS 핵심 (3) (0) | 2023.05.16 |
[CSS] 02. CSS 핵심 (2) (0) | 2023.05.06 |
[CSS] 01. CSS 핵심 (1) (0) | 2023.04.29 |