JS ES6, ES6+ 문법을 알아보자

세바님·2023년 3월 12일
0

수업을 듣고 내용을 정리한 글입니다.

1. Let, const


ES6부터는 변수를 선언할 때 let 또는 const 를 사용할 수 있다.

letconst , 그리고 var 는 어떤 차이점이 있을까?

범위

var 는 전역 범위 또는 함수 범위이며, letconst 는 블록 범위이다.
여기서 블록은 중괄호 속에 있는 모든 코드이다.
하나의 블록은 중괄호 속에 존재하며, 중괄호 안에 있는 모든 것은 블록 범위이다.

// var
if (false) {
  var example1 = 5;
}

console.log(example1); // undefined

// let, const
if (true) {
  let example2 = 5;
  const example3 = 10;
  console.log(example2); // 5
  console.log(example3); // 10
}

console.log(example2); // ReferenceError: example2 is not defined
console.log(example3); // ReferenceError: example3 is not defined

위 코드에서 var 로 선언한 example1은 전역 범위여서 if문 외부에서도 사용할 수 있다. 또한 오류가 아닌 undefined가 뜬 모습.
그에 비해 let 으로 선언한 example2, const 로 선언한 example3은 블록 범위이기 때문에 if문 외부에서 사용이 불가능하다.

초기화

varlet 은 초기화하지 않은 상태로 선언할 수 있지만, const 는 선언 중에 초기화해야한다.

// var
var first;
first = 10; // 오류 없음

// let
let second;
second = 20; // 오류 없음

// const 
const c; // SyntaxError: Missing initializer in const declaration

재선언, 업데이트

var 는 범위 내에서 재할당 및 재선언할 수 있다.
let 은 재할당할 수 있지만, 재선언은 할 수 없다.
const 는 재할당과 재선언 둘 다 불가능하다.

// var
var hello = "Say hi"
var hello = "Say hello" // 재선언 가능
hello = "Say good morning" // 재할당 가능

// let
let hello = "Say hi";
let hello = "Say good morning"; // SyntaxError: Identifier 'hello' has already been declared
hello = "Say hello"; // 재할당 가능

// const 
const hello = "Say hi";
const hello = "Say hello"; // SyntaxError: Identifier 'hello' has already been declared
hello = "Say good morning"; // TypeError: Assignment to constant variable.

호이스팅

호이스팅 : 변수와 함수 선언이 맨 위로 이동되는 매커니즘.

console.log (hi);
var hi = "Say hi"

만약 위와 같이 코드를 짜면, 다음과 같이 해석된다.

var hi;
console.log(hi); // undefined
hi = "Say hi"

그러나 var 대신 let , const 로 변수를 선언한다면 오류가 발생해 이런 문제를 막아준다. letconst 또한 호이스팅이 되지만 var 와는 다르게 undefined로 초기화되지 않기 때문이다.

console.log(hi); // ReferenceError: Cannot access 'hi' before initialization
let hi = "Say hi"; 

push, pop

const 로 선언한 배열은 push , pop 이 가능하다.

const cities = ["Daegu", "Jeonju"];
cities.push("Seoul");  // 오류 없음
console.log(cities); // ['Daegu', 'Jeonju', 'Seoul']
cities.pop("Daegu"); // 오류 없음
console.log(cities); // ['Jeonju', 'Seoul']

const 선언은 재할당이 불가능하다고 했는데, 왜 그런걸까?

pushpop 은 재할당이나 재선언이 아니기 때문이다(...)

그렇다면 pushpop 은 왜 재할당이나 재선언이 아닐까?

const cities = ["Daegu", "Jeonju"]; 로 배열 cities 의 포인터를 지정한 것이고,
cities.push("Seoul"); , cities.pop("Daegu");cities 의 메모리에 접근을 한 것이다.
즉, pushpop 은 포인터를 건드리지 않았기 때문에 재할당이나 재선언이 아니다.

2. Destructuring


Destructuring은 배열이나 객체의 속성을 해체하여 그 값을 개별 변수에 담을 수 있게 하는 기능이다.

// 배열 Destructuring
const number = [1, 2, 3];

// ES5
var num1 = number[0];
var num2 = number[1];
var num3 = number[2];

console.log(num1, num2, num3); // 1 2 3

// ES6
const [num1, num2, num3] = number;

console.log(num1, num2, num3); // 1 2 3

// 객체 Destructuring
const player = {
  name: "Gwon",
  address: {
    city: "Busan"
  }
};

// ES5
console.log(player.name, player.address.city); // Gwon Busan

// ES6
const { name, address: { city } } = player;
console.log(name, city); // Gwon Busan

한번에 할 수도 있다.

let [fisrtName, middleName, lastName] = ["Dylan", "Coding God", "Israel"];
console.log(lastName); // Israel

3. Template Strings


문자열을 ` (백틱) 으로 감싸 사용할 수 있다. 또한, 문자열 안에 변수를 넣을 수도 있다.
${} 안에 변수를 넣으면 된다.

const name = "김철수"
const age = 19

// ES5
console.log("이름 : " + name + ", 나이 : " + age) // 이름 : 김철수, 나이 : 19

// ES6
console.log(`이름 : ${name}, 나이 : ${age}`); // 이름 : 김철수, 나이 : 19

4. for of


for of 문은 객체를 반복하고, 각각의 속성값을 변수에 할당한다.

let incomes = [6200, 6700, 7500];
let total = 0;

for (const income of incomes) {
	console.log(income); // 6200, 6700, 7500
	total += income;
}

console.log(total) // 20400

for in 문과는 어떤 차이가 있을까?

let incomes = [6200, 6700, 7500];

for (const income in incomes) {
	console.log(incomes[income], income); // 6200 '0' 6700 '1' 7500 '2'
}

for in 에서는 각각의 속성의 인덱스를 반환한 모습이다.

5. Arrow Function


화살표 함수는 화살표 (=>) 를 사용하여 보다 간략한 방법으로 함수를 선언할 수 있다.

// 기존 함수
function add(num1, num2) {
	return num1 + num2;
}

var add = function(num1, num2) {
  return num1 + num2;
};

// 화살표 함수
const add = (num1, num2) => {
	return num1 + num2;
}

만약 함수의 매개변수가 한개라면, 괄호를 생략할 수 있다.
또한, 함수 본문에 하나의 명령문만 있다면 중괄호 또한 생략을 할 수 있다.

const meal = food => `I love ${food}`
console.log(meal("chicken")); // I love chicken

6. Spread Operator


Spread Operator는 반복 가능한 객체를 요소 하나 하나로 전개를 시킬 수 있다.

// 예시 
let contacts = ["Mary", "Joel", "Danny"];
let personalFriends = ["David", ...contacts, "Lily"];
console.log(personalFriends); //  ['David', 'Mary', 'Joel', 'Danny', 'Lily']

let person = {
  name: "Adam",
  age: "25",
  city: "Manchester"
};

let employee = {
  ...person,
  salary: 50000,
  position: "Software Developer"
};

console.log(employee)
// {name: 'Adam', age: '25', city: 'Manchester', salary: 50000, position: 'Software Developer'}

7. includes


includes() 메서드는 배열이 특정 요소를 포함하고 있는지 판별한다.

let numArray = [1, 2, 3, 4, 5];
console.log(numArray.includes(2)); // true
console.log(numArray.includes(7)); // false

탐색을 몇 번째 index 부터 시작할것인지 지정할 수도 있다.

let numArray = [1, 2, 3, 4, 5];
console.log(numArray.includes(2)); // true
console.log(numArray.includes(2, 3)); // 3번 인덱스부터 탐색하기 때문에 false

8. Class


class 는 자바스크립트에서 객체 지향 프로그래밍을 지원하기 위해 도입된 문법이다. class 사용하면, 기존에 프로토타입 기반으로 구현되던 객체 생성 방식을 더 직관적으로 사용할 수 있다.

class Animal {
  constructor(type, legs) {
    this.type = type;
    this.legs = legs;
  }

  makeNoise(sound = "Loud Noise") {
    console.log(sound);
  }
  
  static makeNoise2(sound) {
    console.log(sound);
  }
  
  get metaData() {
    return `Type : ${this.type}, legs: ${this.legs}`;
  }
}

이제 이 클래스를 사용하여 다음과 같이 Animal 인스턴스를 생성할 수 있다.

const cat = new Animal("Cat", 4);
cat.makeNoise(); // Loud Noise

또한 static 메서드는 인스턴스를 생성하지 않고도 사용할 수 있다.

Animal.makeNoise2("meow"); // meow

그리고 get 키워드는 메서드를 객체의 프로퍼티처럼 접근할 수 있도록 할 수 있다.

const cat = new Animal("Cat", 4);
console.log(cat.metaData); // Type : Cat, legs: 4 

여기서 metaData 는 메서드가 아닌 getter 이기 때문에 호출할 필요가 없다. 그러니 metaData 뒤에 괄호를 붙이면 안된다.

9. extends


extends 는 클래스에서 상속을 통해 기존 클래스를 확장할 수 있다.
위에 있는 Animal 클래스를 다음과 같이 상속시킬 수 있다.

class Cat extends Animal {
  constructor(type, legs, color) {
    super(type, legs)
    this.color = color;
  }
  
  makeNoise(sound = "meow") {
    console.log(sound);
  }
  
  get metaData2() {
    return `Type : ${this.type}, legs: ${this.legs}, color: ${this.color}`;
  }
}

const cat2 = new Cat("Cat", 4, "white");
cat2.makeNoise(); // meow
console.log(cat2.metaData); // Type : Cat, legs: 4 
console.log(cat2.metaData2); // Type : Cat, legs: 4, color: white

Animal 클래스에 있던 metaData 를 여전히 쓸 수 있는 모습.

또한 부모 클래스와 생성자가 같다면 constuctor 부분은 생략이 가능하다.

class Cat extends Animal {
  makeNoise(sound = "meow") {
    console.log(sound);
  }
}

10. export, import


export 는 파일 안에 있는 함수나 객체를 내보낼 수 있다.

export const name = "..."
export { v1, v2, v3 ... }
export const func = () => {...}
export class Class {...}

import 는 다른 모듈에서 내보낸 함수나 객체를 가져올 수 있다.

import data from "./example";
import { member1 } from "./team";
import { member2 as name } from "./team";

11. fetch, promise, async / await


fetch() 는 웹 브라우저에서 제공하는 네트워크 통신을 위한 API 이다. fetch() 를 사용하면 서버로 HTTP 요청을 보내고, 서버로부터 응답을 받을 수 있다.

fetch(url)
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error(error));

위의 코드에서 fetch() 함수는 서버로부터 JSON 형식의 데이터를 요청한다. fetch() 함수가 Promise 를 반환하므로, 이 Promise 를 체이닝하여 데이터를 처리하는 로직을 작성한다.

첫 번째 then() 메서드에서는 Response 객체에서 json() 메서드를 호출하여 JSON 데이터를 추출한다. 이렇게 추출한 데이터는 두 번째 then() 메서드에서 처리하게 된다. 마지막으로 catch() 메서드를 사용하여 예외 처리를 한다.


Promise 는 비동기 작업의 결과를 나타내는 자바스크립트 객체이다. 비동기 작업이란 일반적으로 네트워크 요청이나 파일 로딩 등이 포함된다. Promise 는 이러한 비동기 작업을 좀 더 편리하게 다룰 수 있도록 도와준다.

const promise = new Promise((resolve, reject) => {
  // 비동기 작업 수행

  if (/* 작업이 성공하면 */) {
    resolve(result);  // 결과를 resolve()에 전달
  } else {
    reject(error);    // 에러를 reject()에 전달
  }
});

promise
  .then(result => {
    // 비동기 작업이 성공한 경우 실행되는 함수
  })
  .catch(error => {
    // 비동기 작업이 실패한 경우 실행되는 함수
  });

Promise 생성자 함수를 호출할 때는, 콜백 함수를 전달한다. 이 콜백 함수는 resolve와 reject라는 두 개의 함수를 인자로 받습니다. 비동기 작업이 성공하면 resolve() 함수에 결과를 전달하고, 실패하면 reject() 함수에 에러를 전달한다.

then() 메서드는 Promise가 resolve되면 실행되는 함수를 등록한다. catch() 메서드는 Promise가 reject되면 실행되는 함수를 등록한다.


async / await 은 ES2017(ES8)에서 도입된 문법으로, Promise 를 기반으로 하고 있다. async 함수는 반드시 Promise 객체를 반환하며, await 키워드를 이용하여 Promise 객체의 처리가 완료될 때까지 코드의 실행을 일시적으로 정지시킬 수 있다.

async function someFunction() {
  try {
    const result1 = await somePromise1();
    const result2 = await somePromise2(result1);
    return result2;
  } catch (error) {
    console.error(error);
  }
}

위의 코드에서 async 함수 someFunction 내부에서는 await 키워드를 사용하여 somePromise1() 함수와 somePromise2(result1) 함수를 차례로 호출하고, 각각의 Promise 처리가 완료될 때까지 실행을 일시적으로 중지한다. 이후에는 Promise 객체의 처리가 완료되면 반환된 값을 변수에 저장하고, 마지막에는 최종 결과 값을 반환한다. try-catch 구문을 사용하여 Promise 객체의 처리 중 발생한 에러를 처리할 수도 있다.

profile
아아

0개의 댓글