[JS] JavaScript 기본 문법
JavaScript 는 “JavaScript 엔진”에 의해 작동된다.
“JavaScript 엔진” 은 브라우저에 기본 탑재되어 있다. 따라서 우리는 크롬, 사파리와 같은 웹 브라우저를 이용해 간단한 JavaScript 코드를 직접 실행해 볼 수 있다.
변수와 상수
- var: 재선언 가능, 재할당 가능 (스코프와 호이스팅 문제로 사용 지양)
- let: 재선언 불가능, 재할당 가능
- const: 초기화 필수, 재선언 및 재할당 불가능
호이스팅(끌어올리는) : 호출문보다 아래에 작성된 선언문들을 상단으로 끌어올려 실행시켜줌
타입
- Number : 숫자값 , 연산 계산 가능, Infinity, -Infinity, NaN 값 포함
- String : 문자열 값, 따옴표로 표현, 덧셈 연산 지원, 변수의 값 동적으로 표현 가능 :
${name}
(템플릿 리터럴 문법) - Boolean : true, false 상태 표현
- Null : 아무런 값도 담겨 있지 않음 표현
- Undefined : 변수를 선언하고 값을 할당하지 않은 상태
형변환
- 묵시적 형 변환 : 자바스크립트 엔진이 알아서 형변환
- 명시적 형 변환 : 직접 형 변환 명시
let num = 10;
let str = "20";
console.log(num + str); // 1020
let str1 = "20";
let strToNum = Number(str1);
console.log(strToNum); //20
let str2 = "10개";
let strToNum2 = parseInt(str2);
console.log(strToNum2); //10
연산자
- null 뱐합 연산자 : ?? null, defined가 아닌 값을 찾아내는 연산자.
let var1;
let var2 = 10;
let var3 = 20;
let var4 = var1 ?? var2;
console.log(var4); //10
- type of 연산자 값의 타입을 문자열로 반환하는 기능을 하는 연산자
let var7 = 1;
let t1 = typeof var7;
console.log(t1); // number
- 삼항 연산자
let var8 = var7 % 2 === 0 ? "짝수" : "홀수";
console.log(var8); // 홀수
조건문
- if
let num = 10;
if (num > 10) {
console.log("num은 10 이상입나다.");
} else if (num > 5) {
console.log("num은 5 이상입나다.");
} else {
console.log("num은 5 미만입나다.");
}
- switch
let animal = "cat";
switch (animal) {
case "cat": {
console.log("고양이");
break;
}
case "dog": {
console.log("강아지");
break;
}
case "bear": {
console.log("곰");
break;
}
default: {
console.log("알 수 없는 동물");
}
}
반복문
- for
for (let idx = 0; idx < 5; idx++) {
console.log(idx);
}
함수
- 함수 표현식
// 함수 선언문
function funcA() {
console.log("funcA");
}
let varA = funcA;
varA();
let varB = function funcB() {
console.log("funcB");
};
varB();
// 익명함수
let varc = function () {
console.log("funcC");
};
varc();
function funcA() {
console.log("funcA");
}
let varA = funcA;
varA();
varB(); // 호이스팅 안됨
varc(); // 호이스팅 안됨
let varB = function funcB() {
console.log("funcB");
};
let varc = function () {
console.log("funcC");
};
- 화살표 함수
let vard = () => 1;
console.log(vard()); // 1
let vare = (value) => {
console.log(value);
return value + 1;
};
vare(11);
콜백함수(Callback Function)
자신이 아닌 다른 함수에, 인수로써 전달된 함수를 의미함
function main(value) {
value();
}
function sub() {
console.log("I am sub");
}
main(sub);
function main(value) {
value();
}
main(() => {
console.log("I am sub");
});
- 콜백함수 활용
function repeat(count) {
for (let idx = 0; idx <= count; idx++) {
console.log(idx);
}
}
function repeatDouble(count) {
for (let idx = 0; idx <= count; idx++) {
console.log(idx * 2);
}
}
function repeatTriple(count) {
for (let idx = 0; idx <= count; idx++) {
console.log(idx * 3);
}
}
function repeat(count, callback) {
for (let idx = 0; idx <= count; idx++) {
callback(idx);
}
}
repeat(
5,
(repeatDouble = (idx) => {
console.log(idx * 2);
})
);
repeat(
5,
(repeatTriple = (idx) => {
console.log(idx * 3);
})
);
스코프
변수나 함수에 접근하거나 호출할 수 있는 범위
-
전역 스코프 : 전체 영역에서 접근 가능
-
지역 스코프 : 특정 영역에서만 접근 가능
객체
-
객체 생성
let obj1 = new Object();
: 객체 생성자 이용let obj2 = {};
: 객체 리터럴 이용
-
객체 프로퍼티
let person = {
name: "yun",
age: 100,
email: "yun@gmail.com",
};
// 프로퍼티 수정
person.name = "YUN";
// 프로퍼티 삭제
delete person.email;
// 프로퍼티 존재 유무 확인
email in person;
배열
여러개의 값을 순차적으로 담을 수 있는 자료형
- 배열 생성자 :
let arrA = new Array();
- 배열 리터럴 :
let arrB = []
Truthy & Falsy
JavaScript 에서는 상황에 따라 참, 거짓이 아닌 값도 참, 거짓으로 판단한다.
- Falsy
let f1 = undefined;
let f2 = null;
let f3 = 0;
let f4 = -0;
let f5 = NaN;
let f6 = "";
let f7 = 0n;
// if(f1) => false
- Truthy 7가지의 Falsy 한 값들을 제외한 값 들
단락 평가(Short-circuit Evaluation)
function returnFalse() {
console.log("False 함수");
return false;
}
function returnTrue() {
console.log("True 함수");
return true;
}
// False 함수
// false
console.log(returnFalse() && returnTrue());
returnFalse() 가 False 이므로 returnTrue()에 접근안함 => 단락평가가 이루어짐
- 단락평가 활용
let person = {
name: "yun",
age: 100,
email: "yun@gmail.com",
};
function printName(person) {
const name = person && person.name;
console.log(name || "person 값 없음");
}
printName(person);
-
Truty Truthy -> 앞에 있는 Truthy 한 값 반환 - Truty && Truthy -> 뒤에 있는 Truthy 한 값 반환
구조 분해 할당
- 배열의 구조 분해 할당
let arr = [1, 2, 3];
let [one, two, three] = arr;
- 객체의 구조 분해 할당
let person = {
name: "yun",
age: 100,
email: "yun@gmail.com",
};
let { name, age, email } = person;
console.log(name, age, email); // yun 100 yun@gmail.com
let { age: myAge, email } = person;
console.log(myAge, email); // 100 'yun@gmail.com'
- 함수의 매개변수
const func = ({ name, age, email }) => {
console.log(name, age, email);
};
func(person);
Spread 연산자와 Rest 매개 변수
- Spread 객체나 배열에 저장된 여러개의 값을 개별로 흩뿌려주는 역할
let arr1 = [1, 2, 3];
let arr2 = [4, ...arr1, 5, 6];
console.log(arr2); // [4, 1, 2, 3, 5, 6]
let obj1 = {
a: 1,
b: 2,
};
let obj2 = {
...obj1,
c: 3,
d: 4,
};
console.log(obj2); // {a: 1, b: 2, c: 3, d: 4}
funcA = (a, b, c) => {
console.log(a, b, c);
};
funcA(...arr1); // 1, 2, 3
-
Rest 나머지 매개변수
-
rest 뒤에 추가적인 매개변수 추가 불가
function funcB(...rest) {
console.log(rest); // 배열에 모든 값 저장
}
funcB(...arr1); // [1, 2, 3]
function funcC(first, ...rest) {
console.log(first);
console.log(rest); // 첫번쨰 원소를 제외한 값
}
funcC(...arr1);
// 1
// [2, 3]
원시타입 vs 객체타입
원시타입과 객체타입이 값이 저장되거나 복사되는 과정이 서로 다르다.
- 원시타입 : 값 자체로써 변수에 저장되고 목사 된다 (Number, String, Boolean …)
불변값이다 (메모리 값 수정 안됨)
let p1 = 1;
let p2 = p1;
p2 = 2;
console.log(p1, p2); //1, 2
- 객체타입 : 참조값을 통해 변수에 저장되고 복사된다 (Object, Array, Function …)
가변값이다(메모리값이 수정된다)
let sample = {
name: "yun",
hobby: "coding",
};
let sample2 = sample; // 얕은복사
sample2.name = "jyun";
let sample3 = { ...sample }; // 깊은복사
sample3.name = "yundev";
console.log(sample); // {name: 'jyun', hobby: 'coding'}
console.log(sample2); // {name: 'jyun', hobby: 'coding'}
console.log(sample3); //{name: 'yundev', hobby: 'coding'}
- 얕은복사 : 객체의 참조값을 복사함 -> 원본객체가 수정될 수 있어 위험함
-
깊은복사 : 새로운 객체를 생성하면서 프로피터만 따로 복사함 -> 원본객체가 수정될 일이 없어 안전함
- 객체 비교 객체간의 비교는 기본적으로 참조값을 기준으로 이루어진다.
console.log(sample === sample2); // true
console.log(sample === sample3); // false
console.log(JSON.stringify(sample) === JSON.stringify(sample3)); //true
객체를 분자열로 변환하는 JSON.stringify() 함수
를 이용하면 깊은 비교 가능
반복문을 이용한 배열이나 객체 순회
- 배열 순회
- 인덱스를 이용한 반복
for (let item of arr) {
console.log(item);
}
- for of 반목
for (let item of arr) {
console.log(item);
}
- 객체 순회
- Object.keys()
let keys = Object.keys(person);
for (let i = 0; i < keys.length; i++) {
console.log(person[keys[i]]);
}
for (let key of keys) {
console.log(person[key]);
}
- Object.values()
let values = Object.values(person);
for (let value of values) {
console.log(value);
}
- for in
for (let key in person) {
const value = person[key];
console.log(value);
}
for (let a in arr) {
console.log(a);
}
배열 메서드
요소 조작
- push : 배열의 맨 뒤에 새로운 요소 추가
- pop : 배열의 맨 뒤에 있는 요소 제거하고 반환
- shift : 배열의 맨 앞에 있는 요소를 제거 반환
- unshift : 배열의 맨 앞에 새로운 요소를 추가
- slice : 배열의 범위를 잘라내서 새로운 배열을 반환
- concat : 배열을 이어 붙여서 새로운 배열을 반환
순회와 탐색
- forEach
arr.forEach(function (item, idx, arr) {
console.log(idx, item * 2);
});
arr.forEach((item) => {
console.log(item * 2);
});
- include 배열에 특정 요소가 있는 지 확인하는 메서드
let isInclude = arr.includes(3);
console.log(isInclude); // true
- indexOf 특정 요소의 인덱스를 찾아서 반환하는 메서드 (얕은 비교)
let idx = arr.indexOf(3);
console.log(idx); // 2
- findIndex 모든 요소를 순회하면서, 콜백 함수를 만족하는 요소의 인덱스를 반환하는 메서드
const findIdx = arr.findIndex((item) => {
if (item === 2) return true;
});
console.log(findIdx); // 2
- find 모든 요소를 순회하면서, 콜백 함수를 만족하는 요소를 반환
const findItem = arr.find((item) => {
if (item === 2) return true;
});
console.log(findItem); // 2
배열 변형
- filter 기존 배열에서 조건을 만족하는 요수들만 필터링하여 새로운 배열로 반환
let filterItem = arr3.filter((item) => item.age === 22);
console.log(filterItem);
- map 모든 요소를 순회하면서, 콜백 함수를 실행하고 그 결과를 모아서 새로운 배열로 반환
const mapResult = arr2.map((item, idx, arr) => {
return item * 2;
});
console.log(mapResult); // [8, 2, 4, 6, 10, 12]
- sort 배열을 사전 순으로 정렬
arr.sort();
// 오름차순
arr.sort((a, b) => {
if (a > b) {
return 1; //b가 a 앞
} else if (a < b) {
return -1; //a가 b 앞
} else {
return 0; // 순서그대로
}
});
-
toSorted() 정렬된 새로운 배열을 반환
-
join(구분자) 배열의 모든 요소를 하나의 문자열로 합쳐서 반환
Date
- Date 객체
let date1 = new Date();
console.log(date1); // Tue Sep 10 2024 09:34:38 GMT+0900 (한국 표준시)
let date2 = new Date("2000-01-01");
console.log(date2); // Sat Jan 01 2000 09:00:00 GMT+0900 (한국 표준시)
let date3 = new Date("2000-01-01/10:10:10");
console.log(date3); // Sat Jan 01 2000 10:10:10 GMT+0900 (한국 표준시)
let date4 = new Date(2000, 0, 1, 10, 10, 10);
console.log(date4); // Sat Jan 01 2000 10:10:10 GMT+0900 (한국 표준시)
- 타임스템프 특정 시간이 “1970.01.01 00시 00분 00초”로 부터 몇 ms가 지났는지 의미하는 숫자 값
let ts1 = date1.getTime();
let date5 = new Date(ts1);
console.log(date5); // Tue Sep 10 2024 09:37:58 GMT+0900 (한국 표준시)
-
시간 요소
- year : getFullYear();
- month : getMonth(); (월은 0부터 시작)
- date : getDate();
- hour : getHours();
- minute : getMinutes();
- seconds = getSeconds();
-
포맷
console.log(date1.toDateString()); // Tue Sep 10 2024
console.log(date1.toLocaleString()); // 2024. 9. 10. 오전 9:42:26
console.log(date1.toLocaleDateString()); // 2024. 9. 10.
console.log(date1.toLocaleTimeString()); // 오전 9:42:26
console.log(date1.toISOString()); // 2024-09-10T00:42:26.313Z
동기와 비동기
동기 : 여러개의 작업을 순서대로 하나씩 처리
자바스크립트는 일반적으로 동기적으로 작업이 실행된다.
비동기 : 여러개의 작업을 순서대로 처리하지 않음, 여러개의 작업을 동시에 실행 가능
자바스크립트의 비동기 작업들은 자바스크립트 엔진이 아닌 Web APIs 에서 실행됨
console.log(1);
setTimeout(() => {
console.log(2);
}, 3000); //web api 에서 실행
console.log(3);
콜백함수
// 음식을 주문하는 상황
function orderFood(callback) {
setTimeout(() => {
const food = "요아정";
callback(food);
}, 2000);
}
orderFood((food) => {
console.log(`${food} 배달왔습니다.`);
});
Promise
비동기 작업을 효율적으로 처리할 수 있게 도와주는 자바스크립트 내장 객체 (콜백 지옥의 해결 방법)
3가지 상태
- 대기 (Pending) : 아직 작업이 완료되지 않은 상태
- 성공 (Fulfilled) : 비동기 작업이 성공적으로 마무리 된 상태
- 실패 (Rejected) : 비동기 작업이 실패한 상태
const promise = new Promise((resolve, reject) => {
// 비동기 작업을 실행하는 함수
//executor
setTimeout(() => {
console.log("안녕");
resolve("resolve"); // 성공상태로 바꿈
// reject("reject")
}, 2000);
});
console.log(promise); // pending 상태
setTimeout(() => {
console.log(promise); // fulfield 상태
}, 3000);
- then 과 catch
promise.then((value) => {
console.log(`then은 ${value} 상태에만 실행`); //then은 resolve 상태에만 실행
});
promise.catch((error) => {
console.log(`catch는 ${error} 상태에만 실행`); //catch는 reject 상태에만 실행
});
promise chaining
promise
.then((value) => {
console.log(`then은 ${value} 상태에만 실행`);
})
.catch((error) => {
console.log(`catch는 ${error} 상태에만 실행`);
});
콜백지옥 해결
function add10(num) {
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
if (typeof num === "number") {
resolve(num + 10);
} else {
reject("num은 숫자 형식이 아닙니다.");
}
}, 2000);
});
return promise;
}
add10(0)
.then((result) => {
console.log(result);
return add10(result);
})
.then((result) => {
console.log(result);
return add10(result);
});
async/await
async : 어떤 함수를 비동기 함수로 만들어주는 키워드, 함수가 프로마스를 반환하도록 변환해준다,
await : async 함수 내부에서만 사용이 가능 한 키워드, 비동기 함수가 다 처리되기를 기다리는 역할
비동기 함수를 동기함수 처럼 처리하게 해줌
async function getData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({
name: "yun",
hobby: "coding",
});
}, 2000);
});
}
async function printData() {
const data = await getData(); //getData() 가 끝나길 기다려줌
console.log(data);
}
printData();
댓글남기기