[JavaScript] ES6+ 기본 문법

DevSeong2·2021년 10월 30일
1

JavaScript

목록 보기
1/1
post-thumbnail

꼭 알아야 할 ES6+ 문법

상수/변수 선언

var 대신에 const 혹은 let을 사용 -> block scope

  • const: 재할당 불가. 내부 속성값은 수정가능 (상수)
    • 변수가 object일 때 내부 속성을 바꾸는 것은 가능
  • let: Lexical Variable Scoping을 지원하는 변수 선언 문법

호이스팅

JavaScript에서 호이스팅(hoisting)이란, 인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것을 의미합니다. var로 선언한 변수의 경우 호이스팅 시 undefined로 변수를 초기화합니다. 반면 letconst로 선언한 변수의 경우 호이스팅 시 변수를 초기화하지 않습니다.
https://developer.mozilla.org/ko/docs/Glossary/Hoisting

console.log(name)

var name = 'test';

console.log(name);

// 결과
> undefined
> test

const, let을 사용하면 호이스팅 X

Object 선언

tom1 === tom2

let tom1 = {
    name: "Tom",
    age: 10,
    region: "Seoul",
}

let tom2 = {
    "name": "Tom",
    "age": 10,
    "region": "Seoul",
}

Key 게산이 필요한 경우

const tom2 = {
     "name": "Tom",
    "age": 10,
    "region": "Seoul"
    ["score" + "1"]: 100,
}

단축 속성명

tom1 === tom2

let name = "Tom";
let age = 10;

let tom1 = {
    name: name,
    age: age,
    print: function() {
        console.log(`name: ${this.name}, age: ${this.age}`);
    }
};

let tom2 = {
    name,
    age,
    print() {
        console.log(`name: ${this.name}, age: ${this.age}`);
    }
};

객체 복사

JS는 Object/Array에 대해서는 대입 시에 얕은 복사 (Shallow Copy)

const obj1 = { value1: 10 };
const obj2 = obj1;
const obj3 = JSON.parse(JSON.stringify(obj1)) // 깊은 복사

obj1.value1 += 1;

console.log(`obj1:`, obj1);
console.log(`obj2:`, obj2);
console.log(`obj3:`, obj3);

JSON.parse() 메서드는 JSON 문자열의 구문을 분석하고, 그 결과에서 JavaScript 값이나 객체를 생성합니다.

JSON.stringify() 메서드는 JavaScript 값이나 객체를 JSON 문자열로 변환

Template Literals

템플릿 리터럴은 내장된 표현식을 허용하는 문자열 리터럴입니다. 여러 줄로 이뤄진 문자열과 문자 보간기능을 사용할 수 있습니다.
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Template_literals

Multi-line string

String Interpolation

`string text ${expression} string text`

백틱(`) 사용

배열 비구조화 (Array Destructuring)

let [name] = ["Tom", 10,"Seoul"] // "Tom" 대입

let [, age,] = ["Tom", 10, "Seoul"] // 10만 대입

let [name, age, region, height] = ["Tom", 10, "Seoul"] // height 값은 undefined

let [name, age, region, height=150] = ["Tom", 10, "Seoul"] // height 디폴트값 할당

객체 비구조화 (Object Destructuring)

const tom = {
    name: "Tom",
    age: 10,
    region: "Seoul"
}

const { age, name, height } = tom;
// 객체에서 필요한 값들만 추출, height는 undefined

const print_person = ({ name }) => {
    console.log(name)
}
const person = {
    name: "Tom",
    age: 10,
    region: {
        country: '서울',
        postcode:'06222'
    }
}

// region은 할당되지 않고 경로로만 사용된 것
const { name, region: { postcode }} = person

전개 연산자 (Spread Operator)

const tom = {
    name: "Tom",
    age: 10,
    region: "Seoul"
}let [name, ...rest] = ["Tom", 10, "Seoul"] // name에는 "Tom", rest에는 나머지 인자가 대입(Array)

// 여러 개의 인자를 전달받을 때 
let printArgs = (...args) => {
    console.log(args)
}

// 
const tom = {
    name: "Tom",
    age: 10,
    region: "Seoul"
}

// 속성명이 중복될 경우, 마지막 값이 대입
const steve = {
    ...tom,
    name: "Steve"
}

리액트에서는 수많은 값들을 불변객체로서 처리

👉 Spread Operator

함수 / Default Parameters

모든 타입의 값들을 디폴트 파라미터로 지정할 수 있다

function hello(name="Tom", age=10) {
    console.log(`나느 ${name}. ${age}`)
}

const get_default_age = () => 10

function hello(name="Tom", age=get_default_age()) {
    console.log(`나느 ${name}. ${age}`)
}

디폴트 값에 함수를 적용할 경우

👉 자바스크립트에서는 값이 필요할 때 호출

함수 / Named Parameters

객체 비구조화를 활용

function print_person1(name, age, region) {
    console.log('1>', name, age, region)
}
print_person1('Tom', 10, 'Seoul') // Index에 맞게 대입

function print_person2({ name, age, region }) {
    console.log('2>', name, age, region)
}
print_person2({ name: 'Tom', age: 10, region: 'Seoul' })

함수 / Arrow Function

return을 사용하지 않아도, 계산된 값을 반환

인자가 1개일 경우, 소괄호 생략 가능

let hello1 = (name, age) => {
    return `안녕. 나는 ${name}. ${age}이야.`;
}

// 함수를 중괄호로 감싸지 않으면, return 문을 쓰지 않아도 반환값으로 사용
let hello2 = (name, age) => `안녕. 나는 ${name}. ${age}이야.`;

this와 arguments를 바인딩하지 않음

모든 객체에는 this가 존재

var tom = {
    name: "Tom",
    print1: function() {
        console.log(`[print1-1] name: ${this.name}`)
        (function() {
            // 내부 function의 this로 변경
            console.log(`[print1-2] name: ${this.name}`)
        })
    }
}

> [print1-1] name: Tom
> [print1-2] name: undefined

함수 / 다양한 형태

const mysum1 = (x, y) => x + y;
const mysum1 = (x, y) => x + y;
const mysum1 = (x, y) => ({x: x,  y: y}); // 콜론으로 인해, 소괄호 필요 (함수로 인지하기 때문)
const mysum1 = (x, y) => {
    return {x: x, y: y}
}

콜백지옥

비동기 개발을 할 때 많이 사용하는 기법

콜백 -> Promise -> async/await

const fs = require('fs')

fs.readdir('.', function (err, files) {
    if (err) {
        cosole.log('Error finding files: ' + err)
    } else {
        console.log(files);
    }
})

// 위 fs.readdir이 끝나기 전에 수행
console.log("ENDED")

콜백 -> Promise -> async/await

const fs = require('fs')
const fsPromises = fs.promises

fsPromises.readdir('.')
    .then(files => {
        cosole.log('Error finding files: ' + err)
    })
    .catch(err => console.error(err))
})

// 위 fsPromises.readdir이 끝나기 전에 수행
console.log("ENDED")

콜백 -> Promise -> async/await

ES8 (ECAM 2017) 부터 지원
await : promise의 then을 기다림 (await를 사용하면 함수는 항상 async)
비동기이지만 동기적인 방식으로 이해할 수 있는 로직

const fs = require('fs')
const fsPromises = fs.promises

async function fn() {
    try {
        let files = await fsPromises.readdir('.');
        console.log(files);
    }
    catch(err) {
        console.error(err)
    }
}

fn() // async 함수이기에,완료 전에 다음 로직이 동작

console.log("ENDED")

모듈 시스템

예전 웹 상의 자바스크립트에서는 script 태그를 통해서만 로딩

2가지 모듈 시스템

  • CommonJS Module: nodejs에서 주로 활용
  • ES6 Module: 리액트에서 주로 활용

모듈 / ES6 module

IE를 포함한 구형 브라우저에서는 미지원

node 이후에 ES6 Module이 나왔기에, node에서는 왠만한 ES6 문법은 지원하지만, 모듈은 ES6 module 지원하지 않고, CommonJS만을 지원

문법: export, import

모듈 / CommonJS

node에서 지원하는 일반적인 모듈 패턴
문법: module.export, require

고차 함수 (High Order Function)

함수를 인자로 받거나 반환이 가능하고, 다른 함수를 조작하는 함수
함수/클래스 역시 모두 객체

Reference

📗 (JavaScript) 함수의 범위(scope) - Lexical Scoping

profile
차근차근

0개의 댓글