ES6

ECMAScript(ES6)는 JavaScript의 표준화된 버전이다. 모든 주요 브라우저는 이 사양을 따르기 때문에 ES6와 JavsScript라는 용어는 서로 바꿔 사용할 수 있다. 이전까지 배운 Javascript의 대부분은 2009년에 완성된 ES5에 있었다. 2015년에 출시된 ES6에는 언어에 강력한 새 기능이 많이 추가 되었다.
ES6를 통해 화살표 함수, 구조 분해, 클래스, 약속 및 모듈을 포함한 새로운 기술을 배울 수 있다.

 

Object.freeze()

let obj = {
  name:"FreeCodeCamp",
  review:"Awesome"
};
Object.freeze(obj);

변경하면 안되는 변수가 존재할 수 있다. Object.freeze는 변경하면 안되는 변수를 넣어 변경을 못하게 막는다.

 

Inline function

const myFunc = function() {
  const myVar = "value";
  return myVar;
}

우리는 가끔 위와 같은 구성의 함수를 사용하고자 할 때가 있다. ES6은 이러한 방식으로 익명 함수를 작성할 필요가 없도록 화살표 함수 구문을 허용한다.

const myFunc = () => {
  const myVar = "value";
  return myVar;
}

만약, 반환값만 존재하는 경우 아래와 같이도 만들 수 있다.

const myFunc = () => "value";

아래처럼 파라미터를 넣어 return 값을 얻을 수도 있다.

const multiplier = (item, multi) => item * multi;
multiplier(4, 2);

아래와 같이 default 값을 지정해 줄 수 있다. 

const greeting = (name = "Anonymous") => "Hello " + name;

console.log(greeting("John"));		// Hello John
console.log(greeting());		// Hello Anonymous

 

 

Spread Operator

function howMany(...args) {
  return "You have passed " + args.length + " arguments.";
}
console.log(howMany(0, 1, 2));
console.log(howMany("string", null, [1, 2, 3], { }));

보다 유연하게 사용할 수 있도록 나머지 매개변수 기능을 제공한다.

var arr = [6, 89, 3, 45];
var maximus = Math.max.apply(null, arr);

위 ES5 코드는 배열의 최대값을 구하는데 사용된다.

const arr = [6, 89, 3, 45];
const maximus = Math.max(...arr);

ES6에서 스프레드 연산자를 통해 위와같이 보다 편리하게 구할 수 있다.

const arr1 = ['JAN', 'FEB', 'MAR', 'APR', 'MAY'];
arr2 = [...arr1];  // COPY

또한, 위와같이 편리하게 복사도 가능하다.

 

 

Destructuring Assignment

const user = { name: 'John Doe', age: 34 };

const name = user.name;
const age = user.age;

위는 ES5에서 할당하는 예시이다.

const { name, age } = user;

아래는 ES6에서 할당하는 예시이다. 

const { name: userName, age: userAge } = user;

다른 변수명을 사용하고 싶다면, 위와같이 사용할 수 있다.

const user = {
  johnDoe: { 
    age: 34,
    email: 'johnDoe@freeCodeCamp.com'
  }
};

const { johnDoe: { age, email }} = user;
const { johnDoe: { age: userAge, email: userEmail }} = user;

위 와 같이도 사용 가능하다.

const [a, b,,, c] = [1, 2, 3, 4, 5, 6];
console.log(a, b, c); // 1, 2, 5

배열에서 쉼표를 사용하여 구조 분해를 통해 배열의 모든 인덱스 값에 액세스 할 수 있다.

let a = 8, b = 6;
[a, b] = [b, a];

위와 같은 swap 방식도 사용 가능하다.

const [a, b, ...arr] = [1, 2, 3, 4, 5, 7];
console.log(a, b);			// [1,2]
console.log(arr);			// [3,4,5,7]

위와 같이 앞 2개를 제거할 수도 있다.

const stats = {
  max: 56.78,
  standard_deviation: 4.34,
  median: 34.54,
  mode: 23.87,
  min: -0.75,
  average: 35.85
};
const half = (stats) => (stats.max + stats.min) / 2.0; 
const half = ({ max, min }) => (max + min) / 2.0;

위와 같이도 사용할 수 있다고 한다. 이건 좀.. 불편해 보이기도 하다. 구조체의 변수명을 다시 확인해줘야 하는 것 아닌가?

 

 

Template Literals

복잡한 문자열을 더 쉽게 생성할 수 있게 해주는 특수한 유형의 문자열이다.

const person = {
  name: "Zodiac Hasbro",
  age: 56
};

const greeting = `Hello, my name is ${person.name}!
I am ${person.age} years old.`;

위와 같이 사용할 수 있다.

 

Object Literals

const getMousePosition = (x, y) => ({
  x: x,
  y: y
});

위의 코드를 아래와 같이 줄여서 사용할 수 있다.

const getMousePosition = (x, y) => ({ x, y });

 

단, 같은 속성 변수명을 가지고 있어야한다.

 

 

Consise Declarative Functions

const person = {
  name: "Taylor",
  sayHello: function() {
    return `Hello! My name is ${this.name}.`;
  }
};

ES5에서 함수를 선언하려면 위와같은 방식으로 선언해야 했다.

const person = {
  name: "Taylor",
  sayHello() {
    return `Hello! My name is ${this.name}.`;
  }
};

ES6에서는 위와같이 보다 간결하게 함수를 작성할 수 있다.

 

 

Use class Syntax to Define a Constructor Function

 
// Explicit constructor
class SpaceShuttle {
  constructor(targetPlanet) {
    this.targetPlanet = targetPlanet;
  }
}

// Implicit constructor 
class Rocket {
}

위와같이 생성자에 변수를 넣어서 초기화해줄 수 있다. 만약, 명시적으로 생성자를 만들어주지 않는다면, 암시적으로 스스로 선언해준다.

 

 

Use getters and setters to Control Access to an Object

class Book {
  constructor(author) {
    this._author = author;
  }
  // getter
  get writer() {
    return this._author;
  }
  // setter
  set writer(updatedAuthor) {
    this._author = updatedAuthor;
  }
}
const novel = new Book('anonymous');
console.log(novel.writer);	//anonymous
novel.writer = 'newAuthor';
console.log(novel.writer);	//newAuthor

위와 같이 사용할 수 있다. java랑 다른점은 getter, setter를 쓸 때 메소드처럼 쓰지 않는다는 것이다. 또한, set을 할 때도 메소드를 가져오는 것이 아닌 그냥 변수명을 저장하듯이 저장한다.

 

 

Create a Module scriptd

javascript는 주로 HTML 웹에서 수행되는 작은 역할로 시작되었다. javascript를 더욱 모듈화하고, 깔끔하고, 유지 관리하기 쉽게 만들기 위해 ES6에서는 javscript 파일 간에 코드를 쉽게 공유하는 방법을 도입했다. 

<script type="module" src="filename.js"></script>

 

위와같이 모듈화하여 Export할 수 있다.

 

 

Use export to Share a Code Block

math_functions.js이라는 수학 연산과 관련된 여러 함수가 포함된 파일이 있다고 가정해보자. 해당 파일 안에는 아래와 같이 함수가 정의되어있고, 다른 파일과 공유하려면 해당 함수 앞에 export를 추가하면 된다.

export const add = (x, y) => {
  return x + y;
}
const add = (x, y) => {
  return x + y;
}

export { add };

위와같은 방법도 가능하다.

 

 

Reuse JavaScript Code Using import

이제 math_functions.js 파일을 공유하여 수학 연산은 가져와 사용할 수 있다.

import { add } from './math_functions.js';

위와 같이 java에서 사용할 때처럼 파일 directory와 파일명을 추가하여 import하면 사용할 수 있다. 단, 가져올 때 사용할 export한 함수명을 적어줘야 한다. export하는 방법은 Go가 강력한 것 같다. 함수를 대문자로만 바꿔주면되기 때문이다.

 

파일에 export된 모든 함수를 가져오려면 *를 사용하면 된다.

import * as myMathModule from "./math_functions.js";
myMathModule.add(2,3);
myMathModule.subtract(5,3);

위와 같이 선언해주고, 사용할 수 있다.

 

Create an Export Fallback with export default

내보내기 기본값이라는 또 다른 export 구문이 있다. 일반적으로 파일에서 하나의 값만 export하는 경우 이 구문을 사용한다고 한다. 또한, 파일이나 모듈에 대한 대체 값을 생성하는 데에도 사용된다고 한다.

export default function add(x, y) {
  return x + y;
}

export default function(x, y) {
  return x + y;
}

첫 번째는 명명된 함수이고, 두 번째는 익명 함수이다. 익명 함수를 사용할 수 있는 이유는 파일에서 1개의 함수만 export하기 때문이다.

 

 

Create a JavaScript Promise

javascript의 Promise는 비동기식으로 무언가를 약속할 때 사용한다. 작업이 완료되면 약속을 이행하거나 이행하지 못하게 된다. 생성자 함수이므로 생성하려면 Promise 키워드를 사용해야 한다. 구문은 아래와 같다.

const myPromise = new Promise((resolve, reject) => {

});

 

 

Complete a Promise with resolve and reject

Promise에는 pending, fulfilled, rejected 3가지 상태가 있다. 생성된 직후의 상태는 pending 상태이다. 이전의 코드의 경우 pending 상태가 지속하고있는 상태다. promise가 성공적으로 마무리되면 상태가 fulfilled로 변하고, resolve 함수를 호출한다. resolve 함수는 promise가 성공적으로 마무리된 결과를 전달한다. promise가 실패하면 rejected 상태로 변하고, reject 함수가 호출된다. reject 함수는 실패이유를 전달한다.  

const myPromise = new Promise((resolve, reject) => {
	//pending
  if(condition here) {
    resolve("Promise was fulfilled");	// fulfilled
  } else {
    reject("Promise was rejected");		// rejected
  }
});

사용 방법은 위와 같다.

 

 

Handle a Fulfilled Promise with then

이러한 promise는 시간이 걸리는 서버 요청이 있을 때 사용하면 유용하다. 이는 메소드를 사용하여 달성할 수 있다.

Promise.prototype.then(onFulfilled, onRejected)

이 then 메소드는  promise의 최종완료(완료 또는 거부)를 위한 콜백 함수를 예약한다. 약속이 이행되면 resolve를 호출, 거부되면 reject가 실행된다. 

myPromise.then(result => {
  
});

선언된 Promise를 위와 같이 사용할 수 있다.

const makeServerRequest = new Promise((resolve, reject) => {
  // responseFromServer is set to true to represent a successful response from a server
  let responseFromServer = true;
    
  if(responseFromServer) {
    resolve("We got the data");
  } else {  
    reject("Data not received");
  }
});

makeServerRequest.then(result => {
  console.log(result);
});

실제로 사용한 방법은 위와같다.

 

 

Handle a Rejected Promise with catch

myPromise.catch(error => {
  
});

위와 같이 then과 비슷한 방법으로 처리한다.

const makeServerRequest = new Promise((resolve, reject) => {
  // responseFromServer is set to false to represent an unsuccessful response from a server
  let responseFromServer = false;
    
  if(responseFromServer) {
    resolve("We got the data");
  } else {  
    reject("Data not received");
  }
});

makeServerRequest.then(result => {
  console.log(result);
});

makeServerRequest.catch(error => {
  console.log(error);
});

실제사용하면 위와같이 사용할 수 있다.

 

다 풀었는데,, ES6 기능이 보다 많은 것 같다. 이후에 프로젝트하면서 알아가도록 해야겠다.

 

 

Reference

'Javascript' 카테고리의 다른 글

Nest.js를 이용한 게시판 API 개발  (0) 2024.07.21
Nest.js Pipes  (0) 2024.06.17
[Nest.js] Module  (0) 2024.06.11
기본 Javascript 문법  (0) 2024.06.04
왜 Javascript & Node.js를 사용할까?  (0) 2024.05.31

+ Recent posts