JavaScript ES6 문법 정리

const and let

ES6에서 추가된 변수 선언 방법입니다.

변수 재 선언

var의 경우 변수를 한번 더 선언했음에도 오류가 발생하지 않습니다.

var foo = "foo"
console.log(foo) // foo
var foo = "pee"
console.log(pee) // pee

let의 경우 변수를 한번 더 선언할 경우 오류가 발생합니다. (const의 경우도 마찬가지로 오류가 발생합니다.)

let foo = "foo"
console.log(foo)
let foo = "pee" // Uncaught SyntaxError: Identifier 'foo' has already been declared
console.log(foo)

const 와 let 차이점

let의 경우 값의 재할당이 가능하지만, const에서는 값을 재할당 할 수 없습니다.

let foo = "foo"
console.log(foo)
// let foo = "pee" // Uncaught SyntaxError: Identifier 'foo' has already been declared
// console.log(foo)
foo = "pee"
console.log(foo)

const foo = "foo"
console.log(foo)
foo = "pee" // Uncaught TypeError: Assignment to constant variable.
console.log(foo)

var의 경우 변수 선언이 사용보다 늦어도 오류가 발생하지 않습니다.

console.log(foo) // undefined
var foo = "foo"

const와 let의 경우

console.log(foo) // Uncaught ReferenceError: Cannot access 'foo' before initialization
let foo = "foo" 

호이스팅

자바스크립트에서는 소스코드를 실행하기전에 소스코드 평가 과정이라는 것을 거치게 됩니다.
이 때 모든 변수와 함수의 선언을 스코프 최상단으로 올리게 되는데, 이를 호이스팅이라고 말합니다.

위 처럼 var이 undefined로 오류가 발생하지 않고 실행된 이유는 호이스팅 때문인데,
위의 var을 사용한 변수 선언은 실제로 아래와 같이 표현됩니다.

var foo
console.log(foo) // undefined
foo = "foo"

그렇다면 let과 const는 호이스팅이 발생하지 않을까?

let, const도 호이스팅이 발생합니다.
그러나 var 처럼 undefined의 할당은 이루어지지 않고, 변수의 선언만 이루어집니다.
이게 구글링을 하다보면 호이스팅 발생한다는 사람들도 있고 아니라는 사람들도 있는데;;
Javascript 공식문서에서 호이스팅이 발생한다고 설명하고 있습니다.
다른 글들에 속지마시길!

화살표 함수

ES6에서 새로 등장한 함수를 선언하는 방법으로 전통적인 함수표현의 간편한 대안이다. (더 간결하다.)

ES5 함수 선언

var foo = function fooFunction(x) { return x * x } 

ES6 화살표 함수 선언

var foo = x => { return x * x }

const(or var or let) 변수명 = (매개변수1, 매개변수2) => { 함수 몸통 }

  • 매개변수가 없을 경우 : () (빈 소괄호를 이용)
  • 매개변수가 하나일 경우 : 매개변수 (소괄호 생략 가능)

람다식을 아신다면 람다식과 비슷하다고 볼 수 있을 것 같습니다.

템플릿 리터럴

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

이전 문법 

function foo(name, age) {
    return name + "의 나이는 " + age + "입니다." 
}
console.log(foo("찬해형", 27)) // 찬해형의 나이는 27입니다.  

템플릿 리터럴 이용

const foo = (name, age) => {
    return `${name}의 나이는 ${age}입니다.`
}
console.log(foo("찬해형", 27)) // 찬해형의 나이는 27입니다.

기본 매개변수

매개 변수를 쓰지 않은 경우 함수의 매개변수에 기본값이 정의되어 있다면 기본값을 사용하도록 합니다.
const foo = (age = 5) => {
return 나이는 ${age}
}
console.log(foo()) // 나이는 5

배열 및 객체 비구조화 할당

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

비구조화 할당을 사용하지 않을 경우 각각 변수 생성 후 object의 key에 접근하여 할당해야합니다.

const object = {
chanhae: "찬해",
inho: "인호",
hyeonwoo: "현우",
seungje: "승제"
}

const ch = object.chanhae
const ih = object.inho
const hw = object.hyeonwoo
const sj = object.seungje

console.log(ch)
console.log(ih)
console.log(hw)
console.log(sj)

비구조화 할당을 사용할 경우 코드가 훨씬 간단해집니다.

const object = {
chanhae: "찬해",
inho: "인호",
hyeonwoo: "현우",
seungje: "승제"
}

const {chanhae, inho, hyeonwoo, seungje} = object

console.log(chanhae)
console.log(inho)
console.log(hyeonwoo)
console.log(seungje)

만약 객체 내의 key값과 다른 이름으로 사용하고 싶다면 아래와 같이 합니다.

const {chanhae: ch, inho, hyeonwoo, seungje} = object

console.log(ch)
console.log(inho)
console.log(hyeonwoo)
console.log(seungje)

// 콜론과 함께 사용할 이름 지정. 
// 만약 객체의 key값과 다르게 사용하면 undefined가 반환됩니다.

비구조화 할당은 배열에서도 같은 방법으로 적용 가능합니다.

나머지 매개변수 및 확장 연산자

나머지 매개변수

현재 인덱스부터 마지막까지 하나의 변수에 할당하고 싶을 때 사용가능합니다.

const arr = ["찬해", "인호", "승제", "현우"]

const [ch, ih, ...rest] = arr

console.log(ch) // 찬해
console.log(ih) // 인호
console.log(rest) // ["승제", "현우"]

만약 arr의 값이 변경되면 나머지 매개변수 연산을 통해 얻은 배열의 값이 변경될까?

나머지 매개변수 사용
// 배열의 값을 변경하기위해 let 으로 선언
let arr = ["찬해", "인호", "승제", "현우"]
// 나머지 매개변수 이용하여 배열 복사
let [ch, ...rest] = arr
// 승제 자리 찬해로 변경
arr[2] = "찬해"

console.log(arr) // ["찬해", "인호", "찬해", "현우"]
console.log(rest) // ["인호", "승제", "현우"]

let arr = ["찬해", "인호", "승제", "현우"]

rest에 arr 바로 대입
let rest = arr

arr[2] = "찬해"

console.log(arr) // ["찬해", "인호", "찬해", "현우"]
console.log(rest) // ["찬해", "인호", "찬해", "현우"]

나머지 매개변수 연산에서는 arr의 값이 변경되어도 rest배열의 값은 변경되지 않았으므로, 깊은 복사가 일어난것을 알 수 있습니다.
배열을 그대로 변수에 대입할 경우, arr의 값이 변경되면 rest 배열의 값도 변경되었습니다.

전개 연산자

const arr = ["찬해", "인호"]
const arr2 = ["승제", "현우"]

const newarr = [...arr, ...arr2]
console.log(arr) // ["찬해", "인호"]
console.log(arr2) // ["승제", "현우"]
console.log(newarr) // ["찬해", "인호", "승제", "현우"]

배열을 이어 붙일 때 전개연산자를 통해 쉽게 이어붙일 수 있다.
객체에서도 가능!

const obj = {ch: "찬해", ih: "인호"}
const obj2 = {sj: "승제", hw: "현우"}

const newobj = {...obj, ...obj2}
console.log(obj) // { ch: "찬해",ih: "인호" }
console.log(obj) // { sj: "승제",hw: "현우" }
console.log(newobj) // { ch: "찬해",ih: "인호", sj: "승제", hw: "현우" }

프로미스

비동기 코드를 사용할 때 쓰기 좋은 ES6문법입니다.
이전에는 라이브러리로 이용할 수 있었으나, ES6부터 언어 차원에서 지원하게 되었다.
책에서는 ES5에서 기본으로 제공한다고 나와있는데.. 구글링하면 다 ES6부터라고 함;;
스택 오버플로우 문서찾아보니 ES6부터 지원하는게 맞는것 같음!

프로미스를 사용하지 않고 비동기 함수를 수행하는 방법

var async1 = function(param, callback) { callback(param*2); }
var async2 = function(param, callback) { callback(param*3); }
var async3 = function(param, callback) { callback(param*4); }

var start = 1;

async1(start, result => {
    async2(result, result => {
        async3(result, result => {
            console.log(result); // 24
        });
    });
});

보는것과 같이 callback 함수가 중첩되면서 들여쓰기 때문에 코드 가독성이 매우 떨어집니다.

function async1 (param) {
return new Promise(function(resolve, reject) { // 프로미스 객체 생성, resolve는 성공, reject는 실패
    resolve(param*2); // 요청이 성공했을 때 resolve를 보낼 수 있음. 만약 에러가 발생했다면 reject()로 오류전달
    });
}
function async2 (param) {
    return new Promise(function(resolve, reject) {
        resolve(param*3);
    });
}
function async3 (param) {
    return new Promise(function(resolve, reject) {
        resolve(param*4);
    });
}

var start = 1;
async1(start)
    .then(async2)
    .then(async3)
    .then(result => {
        console.log(result); // 24
    })
    .catch((err) => {
        console.log(err)
    });

프로미스 요청은 then 메소드로 비동기 요청을 이어붙일 수 있습니다. 이전 promise가 resolve되었다면 그 다음 promise가 실행됩니다.
여러개의 프로미스 체인중 하나라도 reject되었다면 마지막에 달린 catch()로 내려가서 에러를 처리합니다.

fetch 메서드로 promise 체인 사용해보기

function request() {
fetch('https://api.github.com/orgs/nodejs', {
    method: 'GET', // url에 get 요청 보냄.
})
.then(response => { // response 받은 값을 리턴
    return response.json();
})
.then(data => { // 리턴받은 값을 로그로 찍음
    console.log(data);
});
}

request();

실행가능한 코드는 모두 JSFiddle에서 테스트 했습니다.

Reference

https://velog.io/@kimhscom/JavaScript-%EC%9E%90%EC%A3%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94-ES6-%EB%AC%B8%EB%B2%95-%EC%A0%95%EB%A6%AC

https://velog.io/@recordboy/%EC%A0%84%EA%B0%9C-%EC%97%B0%EC%82%B0%EC%9E%90Spread-Operator

https://joshua1988.github.io/web-development/javascript/promise-for-beginners/

https://han41858.tistory.com/11

'TIL' 카테고리의 다른 글

함수 호출 규약(Calling Convention)과 마샬링(marshalling)  (1) 2023.10.17
[키워드 정리] VNC VS RDP, ICMP  (0) 2022.03.09
2021.09.11  (0) 2021.09.11
2021.09.09  (0) 2021.09.10
2021.09.08  (0) 2021.09.08

+ Recent posts