45. javascript 중급 개념 정리

yeah·2023년 7월 28일
0

Today I Learned

목록 보기
32/70
post-thumbnail
post-custom-banner

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)

  1. 숫자 변환
  • Number.toString() 메서드를 사용하여 숫자를 문자열로 변환할 수 있다. 진법을 인수로 주면 해당 진법으로 변환된다.
const num = 10;
console.log(num.toString(2)); // 2진수로 변환: "1010"
console.log(num.toString(16)); // 16진수로 변환: "a"
  1. 수학 메서드
  • 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
  1. 랜덤 숫자
  • 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(", ");
  1. 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]
  1. 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' (기본값이 설정되지 않은 경우)
  1. 객체 구조 분해 할당
  • 객체의 프로퍼티 값을 변수에 할당
  • 프로퍼티 순서를 신경쓰지 않아도 된다.
  • 프로퍼티 이름을 바꿀 수 있다.
  • 기본값을 설정할 수 있다.
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

  • 자바스크립트에서 함수 실행을 시간으로 제어하는 메서드
  1. setTimeout : 일정 시간 후에 함수를 한 번 실행
  2. 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 값을 제어하는 메서드
  1. call : 함수를 호출하면서 첫 번째 매개변수로 지정한 객체를 this로 설정한다. 그리고 추가적인 매개변수를 순서대로 함수에 전달한다.
  2. apply : 함수를 호출하면서 첫 번째 매개변수로 지정한 객체를 this로 설정한다. 그리고 배열 형태의 추가적인 매개변수를 함수에 전달한다.
  3. 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 }

참고 영상

https://youtu.be/4_WLS9Lj6n4

profile
기록과 회고
post-custom-banner

0개의 댓글