Mission: javascript 개념 정리
변수(Variable)
자바스크립트에서 데이터를 저장하고 참조하기 위한 식별자.
- var, let, const 세 가지 키워드를 사용하여 선언할 수 있으며, 블록 스코프를 갖는 let과 const를 권장한다.
// 변수 선언과 할당 let name = "John"; const age = 30; var height = 180; // 변수 값 변경 name = "Jane"; age = 31; // 오류 발생 (const 변수는 재할당 불가능) // 블록 스코프 function exampleFunction() { let x = 10; if (true) { let y = 20; console.log(x); // 출력: 10 console.log(y); // 출력: 20 } console.log(y); // 오류 발생 (y 변수는 블록 내에서만 유효) }
호이스팅
변수 선언이 해당 스코프의 최상단으로 끌어올려지는 동작.
- var 키워드로 선언한 변수는 선언부가 호이스팅되지만 초기화는 실제 코드 위치에서 이루어짐.
console.log(name); // 출력: undefined (변수는 호이스팅되지만 초기화되지 않았음) var name = "John";
생성자 함수(Constructor Function)
객체를 생성하는데 사용되는 함수로, 객체를 생성하고 초기화하는 역할을 한다.
- 생성자 함수는 보통 첫 글자를 대문자로 쓰며, new 키워드를 사용하여 호출된다.
// 생성자 함수 선언 function User(name, age) { this.name = name; this.age = age; this.greet = function() { console.log(`Hello, my name is ${this.name}`); }; } // 객체 생성 (new 키워드 사용) const user1 = new User("John", 30); const user2 = new User("Jane", 25); const user3 = new User("Mike", 40); // 메소드 호출 user1.greet(); // 출력: Hello, my name is John user2.greet(); // 출력: Hello, my name is Jane user3.greet(); // 출력: Hello, my name is Mike
계산된 프로퍼티(Computed property)
객체 내에서 변수를 사용하여 프로퍼티 값을 동적으로 설정하는 방법이다.
[ ] 안에 변수를 넣어 프로퍼티 이름을 결정한다.const key = "name"; const value = "John"; const user = { [key]: value, age: 30, [key + "_surname"]: "Doe", }; console.log(user); // 출력: { name: 'John', age: 30, name_surname: 'Doe' }
객체 메소드(Object methods)
객체 내부에 정의된 함수로, 객체와 관련된 동작을 수행한다. 주로 함수를 객체 프로퍼티로 할당하여 사용한다.
const user = { name: "John", age: 30, sayHello: function () { console.log(`Hello, my name is ${this.name} and I'm ${this.age} years old.`); }, }; user.sayHello(); // 출력: Hello, my name is John and I'm 30 years old.
심볼(Symbol)
유일하고 변경 불가능한 식별자로 사용되는 자료형이다.
- 객체의 프로퍼티 키로 사용되며, 숫자형이나 불린형처럼 만들 수도 있다.
- 심볼은 서로 다른 값을 가지더라도 이름이 같기 때문에 충돌을 방지하는 데 유용하며, 설명을 부여하여 디버깅에 활용할 수도 있다.
// 심볼 생성 const mySymbol = Symbol(); const anotherSymbol = Symbol(); // 객체 생성 및 심볼로 프로퍼티 추가 const myObject = {}; myObject[mySymbol] = "첫 번째 심볼로 추가된 값"; myObject[anotherSymbol] = "두 번째 심볼로 추가된 값"; // 객체 프로퍼티 접근 console.log(myObject[mySymbol]); // 출력: "첫 번째 심볼로 추가된 값" console.log(myObject[anotherSymbol]); // 출력: "두 번째 심볼로 추가된 값" // 같은 이름의 심볼이라도 서로 다른 값으로 취급됨 const sameSymbol = Symbol("같은 이름의 심볼"); const sameSymbol2 = Symbol("같은 이름의 심볼"); console.log(sameSymbol === sameSymbol2); // 출력: false // 심볼은 객체의 키로 사용되어도 숨겨져 보이지 않음 console.log(Object.keys(myObject)); // 출력: [] // 심볼 접근 메서드를 통해 심볼 키 확인 가능 console.log(Object.getOwnPropertySymbols(myObject)); // 출력: [Symbol(), Symbol()]
숫자, 수학 method (Number, Math)
- 숫자 변환
Number.toString()
메서드를 사용하여 숫자를 문자열로 변환할 수 있다. 진법을 인수로 주면 해당 진법으로 변환된다.const num = 10; console.log(num.toString(2)); // 2진수로 변환: "1010" console.log(num.toString(16)); // 16진수로 변환: "a"
- 수학 메서드
Math.ceil()
: 올림하여 정수를 반환Math.floor()
: 내림하여 정수를 반환Math.round()
: 반올림하여 정수를 반환Math.trunc()
: 소수점 이하를 버리고 정수를 반환Math.pow()
: 거듭제곱 값을 반환Math.abs()
: 절대값을 반환Math.sqrt()
: 제곱근 값을 반환const num1 = 5.67; console.log(Math.ceil(num1)); // 올림: 6 console.log(Math.floor(num1)); // 내림: 5 console.log(Math.round(num1)); // 반올림: 6 console.log(Math.trunc(num1)); // 버림: 5 const num2 = -1; console.log(Math.abs(num2)); // 절대값: 1 const num3 = 20; console.log(Math.pow(num3, 3)); // 20의 3제곱: 8000 const num4 = 16; console.log(Math.sqrt(num4)); // 제곱근: 4
- 랜덤 숫자
Math.random()
: 0 이상 1 미만의 무작위 소수를 반환- 원하는 범위에 따라 랜덤한 정수를 구할 수 있다.
// 1부터 100까지의 랜덤 정수 const randomInt = Math.floor(Math.random() * 100) + 1; console.log(randomInt);
문자열 메서드(String methods)
// 문자열 길이 구하기 const str = "Hello, World!"; console.log(str.length); // 13 // 문자열 추출 const text = "Hello, JavaScript!"; const extracted = text.slice(7, 17); console.log(extracted); // "JavaScript" // 문자열 대문자와 소문자로 변환 const name = "John Doe"; console.log(name.toUpperCase()); // "JOHN DOE" console.log(name.toLowerCase()); // "john doe" // 문자열 포함 여부 확인 const sentence = "This is a sample sentence."; console.log(sentence.includes("sample")); // true // 문자열 반복 const star = "*"; const stars = star.repeat(5); console.log(stars); // "*****" // 문자열 비교 const a = "apple"; const b = "banana"; console.log(a < b); // true (알파벳 순서로 비교) // 문자열에서 앞뒤 공백 제거 const message = " Hello, JavaScript! "; console.log(message.trim()); // "Hello, JavaScript!"
배열 메서드
// 배열 생성 const numbers = [1, 2, 3, 4, 5]; // push: 요소 추가 numbers.push(6); // pop: 끝 요소 제거 numbers.pop(); // slice: 인덱스 1부터 3까지 추출 const slicedArray = numbers.slice(1, 4); // splice: 인덱스 2부터 2개 요소를 삭제하고 100, 200 추가 numbers.splice(2, 2, 100, 200); // indexOf: 100의 인덱스 확인 const index100 = numbers.indexOf(100); // find: 짝수 찾기 const evenNumber = numbers.find((num) => num % 2 === 0); // filter: 짝수 요소 필터링 const evenNumbersArray = numbers.filter((num) => num % 2 === 0); // map: 모든 요소에 10을 더하여 새로운 배열 생성 const newNumbersArray = numbers.map((num) => num + 10); // join: 배열 요소를 문자열로 합치기 (구분자: ", ") const joinedString = numbers.join(", "); // split: 문자열을 배열로 분할 (구분자: ", ") const splitArray = joinedString.split(", ");
- sort 메소드:
배열을 재정렬하는 기능을 제공
- 숫자 배열의 경우, 기본적으로 알파벳 순서가 아닌 크기 순서로 정렬된다.
- 숫자 배열을 올바르게 정렬하기 위해서는 정렬 기준을 비교할 함수를 전달해야 한다.
const numbers = [13, 2, 8, 5, 23, 4, 10, 7]; numbers.sort((a, b) => a - b); // 결과: [2, 4, 5, 7, 8, 10, 13, 23]
- reduce 메소드
배열의 요소를 하나로 축소하여 반환하는 기능을 제공
- 초기값과 현재 값의 조합을 사용하여 배열 요소를 처리한다.
const numbers = [1, 2, 3, 4]; const sum = numbers.reduce((acc, current) => acc + current, 0); // 결과: 10 (1 + 2 + 3 + 4)
구조 분해 할당(Destructuring assignment)
배열이나 객체의 속성을 변수에 분해하여 할당하는 기능이다. 각 변수에 해당하는 값을 바로 할당할 수 있다.
1. 배열 구조 분해 할당
- 배열에서 순서대로 값을 변수에 할당
- 값이 없을 경우, 기본값을 설정할 수 있다.
- 필요하지 않은 요소는 공백 또는 쉼표로 무시할 수 있다.
const users = ['Alice', 'Bob', 'Charlie']; const [user1, , user3 = 'Unknown'] = users; // 결과: user1 = 'Alice', user3 = 'Charlie' (기본값이 설정되지 않은 경우)
- 객체 구조 분해 할당
- 객체의 프로퍼티 값을 변수에 할당
- 프로퍼티 순서를 신경쓰지 않아도 된다.
- 프로퍼티 이름을 바꿀 수 있다.
- 기본값을 설정할 수 있다.
const user = { name: 'Alice', age: 30, gender: 'female' }; const { name, gender: userGender = 'male' } = user; // 결과: name = 'Alice', userGender = 'female' (기본값이 설정되지 않은 경우)
나머지 매개변수(Rest parameters)
- 함수에서 정해지지 않은 개수의 인수를 배열로 받을 수 있게 한다.
- 함수 내에서
...이름
형태로 사용하며, 이름에 전달된 인수들이 배열로 저장된다.function printNames(name, ...others) { console.log(name); // 출력: 'Alice' console.log(others); // 출력: ['Bob', 'Charlie'] } printNames('Alice', 'Bob', 'Charlie');
전개 구문(Spread syntax)
- 배열이나 객체를 펼쳐서 개별 요소로 사용할 수 있게 한다.
- 배열에서
[...배열]
, 객체에서{...객체}
형태로 사용한다.const arr1 = [1, 2, 3]; const arr2 = [4, 5, 6]; const combinedArr = [...arr1, ...arr2]; // 결과: [1, 2, 3, 4, 5, 6] const user1 = { name: 'Alice', age: 30 }; const user2 = { name: 'Bob', gender: 'male' }; const mergedUser = { ...user1, ...user2 }; // 결과: { name: 'Bob', age: 30, gender: 'male' }
클로저
- 함수와 그 함수가 생성될 당시의 외부 변수를 기억하는 기능이다.
- 생성 이후에도 외부 변수에 접근 가능하며, 함수의 실행이 끝나도 접근이 유지된다.
function makeCounter() { let count = 0; return function() { return ++count; }; } const counter1 = makeCounter(); console.log(counter1()); // 출력: 1 console.log(counter1()); // 출력: 2 const counter2 = makeCounter(); console.log(counter2()); // 출력: 1
setTimeout
,setInterval
- 자바스크립트에서 함수 실행을 시간으로 제어하는 메서드
setTimeout
: 일정 시간 후에 함수를 한 번 실행setInterval
: 일정 시간 간격으로 함수를 반복해서 실행// setTimeout 예제 setTimeout(() => { console.log('3초 후에 실행됩니다.'); }, 3000); // setInterval 예제 let count = 0; const intervalId = setInterval(() => { count++; console.log(`${count}초 지났습니다.`); if (count === 5) { clearInterval(intervalId); // 5번 실행 후 반복 종료 } }, 1000);
call
,apply
,bind
- JavaScript에서 함수의 this 값을 제어하는 메서드
call
: 함수를 호출하면서 첫 번째 매개변수로 지정한 객체를 this로 설정한다. 그리고 추가적인 매개변수를 순서대로 함수에 전달한다.apply
: 함수를 호출하면서 첫 번째 매개변수로 지정한 객체를 this로 설정한다. 그리고 배열 형태의 추가적인 매개변수를 함수에 전달한다.bind
: 함수의 this 값을 영구적으로 지정한 새로운 함수를 생성한다.const mike = { name: 'Mike', sayHi: function() { console.log(`Hello, I'm ${this.name}.`); }, }; const tom = { name: 'Tom', }; // call 예제 mike.sayHi.call(tom);// 출력: Hello, I'm Tom. // apply 예제 const args = ['John', 'engineer']; mike.sayHi.apply(tom, args); // 출력: Hello, I'm Tom. // bind 예제 const updateMike = mike.sayHi.bind(tom); updateMike(); // 출력: Hello, I'm Tom.
상속과 프로토타입
- 프로토타입은 객체를 생성할 때, 해당 객체가 가지지 않은 프로퍼티를 프로토타입 체인을 통해 상위 객체에서 찾아 사용하는 개념이다.
- 객체가 프로퍼티를 읽거나 호출할 때 해당 객체에 없으면 프로토타입으로 올라가서 찾는다.
// 상위 객체인 'Car' 생성자 함수와 프로토타입을 만든다. function Car() { this.color = 'blue'; } Car.prototype.drive = function() { console.log('Driving...'); }; // 'BMW' 생성자 함수를 만들고 상속을 설정한다. function BMW() { this.make = 'BMW'; } BMW.prototype = Object.create(Car.prototype); // 상속 설정 BMW.prototype.honk = function() { console.log('Honk honk!'); }; const bmwCar = new BMW(); console.log(bmwCar.color); // 'blue' (부모 객체에서 상속된 프로퍼티) bmwCar.drive(); // 'Driving...' (부모 객체에서 상속된 메서드) bmwCar.honk(); // 'Honk honk!' (자신의 메서드)
클래스
- 객체 생성을 위해 사용되는 ES6의 기능으로, 생성자 함수와 유사하게 객체를 초기화하는 메서드인 생성자를 내부에 정의한다.
- 객체 생성에는 new 키워드를 사용하고, 클래스 내부에 메서드를 추가하여 객체의 동작을 정의한다. 또한, 상속을 구현하기 위해 extends 키워드를 사용하여 클래스 간에 상속 관계를 정의한다.
class Car { constructor(name, color) { this.name = name; this.color = color; } drive() { console.log(this.name + " is driving."); } } class BMW extends Car { constructor(color) { super("BMW", color); } drive() { super.drive(); console.log("Vroom!"); } } const myCar = new Car("Toyota", "blue"); const myBMW = new BMW("black"); myCar.drive(); // Output: Toyota is driving. myBMW.drive(); // Output: BMW is driving. // Vroom!
프로미스(Promise)
- 프로미스는 비동기 작업을 처리하는 객체로, 성공 또는 실패 결과를 다룬다.
- 프로미스는 resolve 함수로 성공 시 결과를 반환하고, reject 함수로 실패 시 에러를 반환한다.
- .then()을 사용하여 성공 시 처리, .catch()를 사용하여 실패 시 처리를 할 수 있다.
// 예시 코드: 프로미스로 비동기 작업 처리 function orderItem(item) { return new Promise((resolve, reject) => { // 비동기 작업 수행 setTimeout(() => { if (item === "productA") { resolve("Product A is ready!"); } else { reject(new Error("Failed to prepare the item.")); } }, 3000); // 3초 뒤에 결과 반환 }); } // 프로미스 사용 orderItem("productA") .then((result) => console.log(result)) .catch((error) => console.error(error.message));
async와 await
프로미스를 간결하게 다루기 위한 JavaScript의 기능
async
키워드를 사용하여 함수가 항상 프로미스를 반환하도록 설정할 수 있다.await
키워드를 사용하여 비동기 작업이 완료될 때까지 기다릴 수 있다.try-catch
를 사용하여 에러를 처리한다.// 예시 코드: async와 await를 사용한 비동기 작업 async function orderItem(item) { try { // 비동기 작업 수행 await new Promise((resolve) => setTimeout(resolve, 1000)); // 1초 기다림 if (item === "productA") { return "Product A is ready!"; } else { throw new Error("Failed to prepare the item."); } } catch (error) { console.error(error.message); } } // 함수 호출 async function main() { const result1 = await orderItem("productA"); console.log(result1); const result2 = await orderItem("productB"); console.log(result2); const result3 = await orderItem("productC"); console.log(result3); } main();
제네레이터
함수 실행을 중간에 멈추고 다시 이어서 진행할 수 있는 독특한 기능
주로 리덕스 사가와 같은 상태 관리 라이브러리에서 활발히 사용된다.
function*
키워드를 사용하여 제네레이터 함수를 생성한다.yield
키워드를 사용하여 실행을 멈추고 값을 반환한다.next()
메서드를 호출하여 제네레이터 함수를 다시 실행하고, yield 표현식까지 실행한다// 예시 코드: 제네레이터 함수와 next() 메서드 사용 function* myGenerator() { yield 1; yield 2; yield 3; } const gen = myGenerator(); console.log(gen.next()); // { value: 1, done: false } console.log(gen.next()); // { value: 2, done: false } console.log(gen.next()); // { value: 3, done: false } console.log(gen.next()); // { value: undefined, done: true }
참고 영상