ES6 문법 정리

fe_sw·2022년 8월 7일
0

ES6

목록 보기
2/2
post-thumbnail

ES6(ECMAScript6)

ES6는 ECMA라는 국제 기구에서 만든 표준문서인 ECMAScript(=ES)의 6번째 개정판 문서에 있는 표준 스펙을 말한다. 6번째 버전이 2015년에 나왔기 때문에 ES2015라고도 한다.

const and let

let와const는 var와 다르게 동일하게 모두 블럭 범위이고 ,변수선언과 초기화가 분리되서 진행된다(호이스팅 관련)

// ES5
var MyBtn = document.getElementById('mybtn');

// ES6
const MyBtn = document.getElementById('mybtn');
위의 코드에서 const는 변경되지 않으며 재할당할 수 없다. 

let은 새로운 값을 가질 수도 있고 재할당할 수도 있습니다. 변경 가능한 변수가 생성된다.

let name = '철수';

name = '영희';

console.log(name); //영희

Arrow functions

화살표함수는 일반함수와 다르게 화살표 함수는 선언할 때 this에 바인딩할 객체가 정적으로 결정되며,
언제나 상위스코프의 this를 가리킨다.생성자 함수로 사용할 수도 없다. 또한 화살표 함수에서는 arguments 변수가 전달되지 않는다

// ES5
function myFunc(name) {
	return '안녕' + name;
}

console.log(myFunc('영희'));

// 출력 => 안녕 영희
다음을 사용합니다.

// ES6 화살표 함수
const myFunc = (name) => {
	return `안녕 ${name}`;
}

console.log(myFunc('영희')); // 출력 => 안녕 영희

// 또는 화살표를 사용하거나 'return' 키워드를 사용하지 않아도 된다
const myFunc = (name) => `안녕 ${name}`;

console.log(myFunc('영희')); // 출력 => 안녕 영희


// ES5
const myArrary = ['진수', '영철', '영희', 5];

let arr1 = myArrary.map(function(item) {
	return item;
});

console.log(arr1); // 출력 => (4) ["진수", "영철", "영희", 5]

// ES6
let arr2 = myArrary.map((item) => item);

console.log(arr2); // 출력 => (4) ["진수", "영철", "영희", 5]

Template Literals

자열을 연결하기 위해 더하기(+) 연산자를 사용할 필요는 없으며, 백틱(`)을 사용하여 문자열 내에서 변수를 사용할 수도 있다.

이전 문법:

// ES5
function myFunc1() {
	return '안녕' + name + '너의 나이는' + age + '살 이다!'; 
}

console.log(myFunc1('영희', 22));
// 출력 => 안녕 영희 너의 나이는 22살 이다!
새로운 ES6 문법 사용:

// ES6
const myFunc = (name, age) => {
	return `안녕 ${name}, 너의 나이는 ${age}살 이다!`; 
};

console.log(myFunc1('영희', 22));

Default parameters

매개 변수를 쓰지 않은 경우 매개 변수가 이미 기본값에 정의되어 있으므로 정의되지 않은 오류가 반환되지 않는다. 따라서 누락된 매개 변수를 사용하여 함수를 실행할 때 기본 매개 변수 t 값을 사용하고 오류를 반환하지 않는다

const myFunc = (name, age) => {
	return `안녕 ${name} 너의 나이는 ${age}살 이니?`; 
};

console.log(myFunc1('영희')); // 출력 => 안녕 영희 너의 나이는 undefined살 이니?
위의 함수는 정의되지 않은 상태로 반환된다. 두 번째 매개 변수 age를 지정하지 않았기 떄문이다


그러나 기본 매개 변수를 사용하면 정의되지 않은 매개 변수가 반환되지 않고 매개 변수 할당을 잊어버렸을 때 해당 값이 사용된다

const myFunc = (name, age = 22) => {
	return `안녕 ${name} 너의 나이는 ${age}살 이니?`; 
};

console.log(myFunc1('영희'));// 출력 => 안녕 영희 너의 나이는 22살 이니?

Spread Operator

Spread Opertor는 배열,객체 중괄호 대괄호를 제거해주는 역활을 한다

// 배열
let array2= ['hello', 'world'];
console.log(array2); //['hello', 'world']
console.log(...array2); //hello world

// 변수
let letter= 'hello';
console.log(letter); //hello
console.log(...letter);//h e l l o 

// deep copy
var a = [1,2,3];
var b = [4,5];
var c = [...a, ...b];

c = [1,2,3,4,5]// (deep copy할떄 유용)

//등호로 복사를 하면 a와 b 변수는 [1,2,3]을 각각 따로 하나씩 가진게 아니라 값 공유가 일어난다
var a = [1,2,3];
var b = a;

// 객체 property copy
let o1 = { a : 1, b : 2};
let o2 = { a : 3, ...o1 };
console.log(o2);

// 이렇게 a라는 값이 중복이 발생하면  뒤에 오는 a로 적용
// 출력해보면 a : 1 이라는 자료가 담겨짐


// 함수 파라미터 넣을떄
function add(a,b,c){
   console.log(a + b + c)
}
let array= [10, 20, 30];
add(...array);  //요즘방식
add.apply(undefined, array); //옛날방식// add(array[0], array[1], array[2]); 

Rest Parameter

Rest Parameter는 파라미터값을 배열로 받을 수 있게 해준다.
따라서 파라미터가 몇개가 오는지 미리 정해지 않아도 된다.

// 배열
function printAll( ...args ) {   //배열형태로 파라미터가 전달 -> ['seok' , 'woo' , 'jjang']
for(let i =0; i<args.length; i++){
    console.log(arg[i]);
}
}
printAll('seok','woo','jjang')
// 출력:
// seok
// woo
// jjang

// args.forEach((arg) => console.log(arg)) 또는
// for(const arg of args) {
//    console.log(arg);
// }
// 표현도 가능하다 

function fun2(a, b ,...parameter){
  console.log(parameter)
}
fun2(1,2,3,4,5,6,7); //[3,4,5,6,7]

//function fun2(a, ...parameter, b){} //에러 :rest parameter는 항상 맨뒤에 써야됨
//function fun2(a, ...parameter, ...parameter2){} //에러:2개 이상 사용할 수 없습니다. 

 

//rest parameter: 파라미터 경우 : []로 씌움
//spread operator:나머지 경우: [],{}을 벋김

 

Arguments

Arguments는 함수 파라미터로 들어온 것을 배열로 담아 사용할 수 있게 해준다.
Arguments는 객체는 모든 함수 내에서 이용 가능한 지역 변수이다.

arguments 객체를 사용하여 함수 내에서 모든 인수를 참조할 수 있으며, 호출할 때 제공한 인수 각각에 대한 항목을 갖고 있다. Rest Parameter와 헷갈리니 잘 구분해서 사용하길 바란다.

// 배열
function arg(a,b,c){
  console.log(arguments)
}
arg(2,3,4); //[2,3,4]


function 함수(a,b,c){
  for (var i = 0; i < arguments.length; i++){
    console.log(arguments[i])
  }
}
함수(2,3,4);
// 출력:
// 2
// 3
// 4

//arguments: 모든파라미터들을 []에 담음
//rest parameter 이자리에 오는 파라미터를 []에 담음

 

Array and object destructing

비구조화를 통해 배열 또는 객체의 값을 새 변수에 더 쉽게 할당할 수 있다.

이전 문법:

// ES5 문법
const contacts = {
	famillyName: '이',
	name: '영희',
	age: 22
};

let famillyName = contacts.famillyName;
let name = contacts.name;
let myAge = contacts.age;

console.log(famillyName);
console.log(name);
console.log(age);
// 출력
// 이
// 영희
// 22
ES6 문법 사용:

// ES6 문법
const contacts = {
	famillyName: '이',
	name: '영희',
	age: 22
};

let { famillyName, name, age } = contacts;

console.log(famillyName);
console.log(name);
console.log(age);
// 출력
// 이
// 영희
// 22
ES5에서는 각 변수에 각 값을 할당해야 하지만 ES6에서는 객체의 속성을 얻기 위해 값을 중괄호 안에 넣는다.

참고: 속성 이름과 동일하지 않은 변수를 할당하면 undefined가 반환된다. 
예를 들어, 속성의 이름이 name이고 username 변수에 할당하면 undefined를 반환합니다.

우리는 항상 속성의 이름과 동일하게 변수 이름을 지정해야합니다. 그러나 변수의 이름을 바꾸려면 콜론을 :대신 사용할 수 있습니다.

// ES6 문법
const contacts = {
	famillyName: '이',
	name: '영희',
	age: 22
};

let { famillyName, name: ontherName, age } = contacts;

console.log(ontherName);// 영희

배열의 경우 객체와 동일한 구문을 사용한다. 중괄호를 대괄호로 바꾸면된다.

const arr = ['광희', '지수', '영철', 20];

let [value1, value2, value3] = arr;

console.log(value1);
console.log(value2);
console.log(value3);
// 출력
// 광희
// 지수
// 영철

Import and export

JavaScript 응용프로그램에서 import 및 export를 사용하면 별도의 재사용 가능한 구성요소를 작성할 수 있다.

export를 사용하면 다른 JavaScript 구성 요소에 사용할 모듈을 내보낼 수 있다. 우리는 그 모듈을 우리의 컴포넌트에 사용하기 위해 가져오기 import를 사용하면 된다.

// ES6
export default function detail(name, age) {
	return `안녕 ${name}, 너의 나이는 ${age}살 이다!`;
}


import detail from './detailComponent';

console.log(detail('영희', 20));


import { detail, userProfile, getPosts } from './detailComponent';

console.log(detail('영희', 20));
console.log(userProfile);
console.log(getPosts);

Promise

Promise는 ES6의 비동기 코드를 쓰는 방법이다. 예를 들어 API에서 데이터를 가져오거나 실행하는데 시간이 걸리는 함수를 가지고 있을 때 사용할 수 있다.

Promise 개체는 비동기 작업이 맞이할 미래의 완료 또는 실패와 그 결과 값을 나타낸다.
매개변수resolve 와 reject 는 함수로서 호출되면 promise 를 이행하거나 거부한다.
이 둘을 이용하여 비동기 작업이 모두 끝나면 resolve 를 호출해 이행하고, 중간에 오류가 생기면 reject 를 이용해 거부하게 된다.

우선 Promise 는 매개변수로 executor 를 받게 된다. executor 는 resolve 와 reject 인수를 전달할 실행함수이다.

const promise = new Promise((resolve, reject)=>{});
console.log(promise);// Promise { <pending> }

const promise2 = new Promise((resolve, reject)=>{
    setTimeout(()=>{
      resolve("resolve");
    }, 3000);
  });
  console.log(promise2);
  setInterval(()=>{
    console.log(promise2);
  }, 1000);
  /*
  Promise { <pending> }
  Promise { <pending> }
  Promise { <pending> }
  Promise { 'resolve' }
  Promise { 'resolve' }
  Promise { 'resolve' }
  */
//   Promise 의 then 과 catch

// then
// promise 가 종료가 되면 resolve 에 들어간 값을 받을 수 있습니다.
const promise3 = new Promise((resolve, reject)=>{
  setTimeout(()=>{
    resolve("resolve");
  }, 3000);
});

promise3.then(value => console.log(value)); 
// 3초 후에 결과가 출력
// resolve


// catch
// 하지만 reject 된 경우에는 then 으로 받을 경우, 에러가 발생합니다.
const promise4 = new Promise((resolve, reject)=>{
    setTimeout(()=>{
      reject("reject");
    }, 3000);
  });
  
promise4.then(value => console.log(value)); // UnhandledPromiseRejectionWarning: reject


// 이 때 catch 를 사용하여 에러를 잡아줄 수 있습니다.
//then,cathch는 같이 실행될수x
promise4.then(result => console.log(result)).catch(error => console.log(error));
// 3초 후에 결과가 출력
// reject

//Chaining Promise
// 상황에 따라 promise 를 여러 번 사용해야 하는 경우가 존재합니다. 
// API 로 data 를 받아오기 위해서 promise 를 사용하고 
// 받아온 데이터의 암호를 풀기 위해서 promise 를 한 번 더 사용할 수 있습니다.
// 이를 Chaining Promise 라고 합니다.

const promise5 = new Promise((resolve, reject)=>{
    resolve(2);
  });
  
  promise5.then(result => {
    const output = result+1;
    console.log(output);   // 3
    return output;
  })
  .then(result => {
    const output = result+1;   // 4
    console.log(output);
    return output;
  })

// 그런데 중간의 chain 에서 에러가 발생하면 어떻게 될까요?
// 이를 해결하기 위해서 각 then 마다 catch 를 넣어줘야 할까요?
// 다행히도 catch 는 한 번의 사용으로 모든 then 에 대해서 해결할 수 있습니다. ->하지만 어디서 에러났는지 판단하기 힘듬 (async await의 탄생배경)
const promise6 = new Promise((resolve, reject)=>{
    resolve(2);
  });
  
  const plusOne = num => num + 1;
  
  promise
  .then(plusOne)
  .then(plusOne)
  .then(plusOne)
  .then(()=> {
    throw Error("error")
  })
  .then(result => console.log(result))
  .catch(error => console.log(error));
// Promise all
// all() 은 주어진 모든 Promise 를 실행한 후 진행되는 하나의 Promise 를 반환합니다.
// 3개의 promise 에 대해 이들을 array 로 all 에 넘겨주면 allPromise 는 3개의 promise가 모두 끝날 때 까지 기다린 후에 이들의 결과값을 array로 반환하게 됩니다.
const p1 = new Promise(resolve => {
  setTimeout(resolve, 2000, "First");
})

const p2 = new Promise(resolve => {
  setTimeout(resolve, 1000, "Second");
})

const p3 = new Promise(resolve => {
  setTimeout(resolve, 3000, "Third");
})

const allPromise = Promise.all([p1,p2,p3]);
allPromise.then(values => console.log(values));// [ 'First', 'Second', 'Third' ]


// 이 중 하나의 promise 에서 에러가 발생한다면 어떻게 될까요?
// allPromise 는 모든 promise 에 대해서 결과값을 받아와야 하는데 그러지 못하므로 에러가 발생하게 됩니다
//이 경우 catch 는 각 promise 에 해줄 필요는 없고, allPromise 에 대해서만 해주면 됩니다.

const allPromise2 = Promise.all([p1,p2,p3]);
allPromise2
.then(values => console.log(values))
.catch(error => console.log(error));
// First reject


// Promise race
// race() 는 주어진 Promise 중 가장 먼저 완료된 것의 결과값을 이행하거나 거부합니다.
// 위에서 살펴본 all 과 사용하는 방법은 같습니다.
// p1 은reject 하고 있지만 결과는 Second 가 나옵니다.
// p2 는 1초만에 끝나기 때문에 그 결과값을 받아 바로 출력해버리는 것이죠.
const p11 = new Promise((resolve, reject) => {
  setTimeout(reject, 2000, "First reject");
})

const p22 = new Promise(resolve => {
  setTimeout(resolve, 1000, "Second");
})

const p33 = new Promise(resolve => {
  setTimeout(resolve, 3000, "Third");
})

const allPromise3 = Promise.race([p11,p22,p33]);
allPromise3
.then(values => console.log(values))   // Second
.catch(error => console.log(error));

//   Promise finally
// finally() 는 Promise 가 resolve 되던 reject 되던 상관없이 지정된 함수를 실행합니다.
// 이를 통해 promise 의 결과에 상관없이 동작을 해야할 때 유용하게 구현할 수 있습니다.
// 해당 예시가 중간에 에러가 발생하고 이를 catch 로 잡아주었어도 finally 는 실행되어 end 를 출력합니다.
const p5 = new Promise((resolve, reject) => {
  setTimeout(resolve, 2000, "First");
});

p5
.then(result => console.log(result))// First 
.finally(()=>console.log("end")); // end


Classes

class는 객체 지향 프로그래밍(OOP)의 핵심이다. 코드를 더욱 안전하게 캡슐화할 수 있습니다. class를 사용하면 코드 구조가 좋아지고 방향을 유지합니다.

class를 만들려면 class 키워드 뒤에 두 개의 중괄호가 있는 class 이름을 사용한다.

class myClass {
	constructor() {
	
	}
}
이제 new 키워드를 사용하여 class 메서드와 속성에 액세스할 수 있습니다.

class myClass {
	constructor(name, age) {
		this.name = name;
		this.age = age;
	}
}

const user = new myClass('영희', 22);

console.log(user.name); // 영희
console.log(user.age); // 22
다른 class에서 상속하려면 extends 키워드 다음에 상속할 class의 이름을 사용합니다.

class myClass {
	constructor(name, age) {
		this.name = name;
		this.age = age;
	}

	sayHello() {
		console.log(`안녕 ${this.name} 너의 나이는 ${this.age}살이다`);
	}
}

// myClass 메서드 및 속성 상속
class UserProfile extends myClass {
	userName() {
		console.log(this.name);
	}
}

const profile = new UserProfile('영희', 22);

profile.sayHello(); // 안녕 영희 너의 나이는 22살이다.
profile.userName(); // 영희


참고

0개의 댓글