Language/Javascript

Javascript - 고차함수 + 자주 쓰이는 ES6~ES12 문법 정리

둉이 2021. 7. 24. 23:09

forEach(element, index, array)

입력받은 배열의 요소와 인덱스를 차례대로 반환

리턴값 없음, for문처럼 사용

let arr = [1, 2, 3, 4, 5]
arr.forEach(e => console.log(e))  // 차례대로 1, 2, 3, 4, 5 출력

 

for ... in / for ... of

forEach에서 할 수 없는 break, continue 등 사용 가능

for ... of는 배열의 요소 값을 차례대로 반환

for ... in은 객체의 key값을 차례대로 반환 (배열에서의 for ... in은 인덱스를 순서대로 반환)

let arr = [1, 3, 5, 7, 9]
let kmj = { name: '미정', age: 25, job: '개발자' }

for (let e of arr) { console.log(e) }  // 차례대로 1, 3, 5, 7, 9 리턴
for (let e in arr) { console.log(e) }  // 차례대로 0, 1, 2, 3, 4 리턴
for (let e in kmj) { console.log(e) }  // 차례대로 name, age, job 리턴

 

map(element, index) / flatMap(element, index)

입력받은 조건 기준으로 입력받은 배열과 같은 길이의 배열을 리턴

flatMap은 map() + flat(중첩배열 삭제) 수행

let arr = [1, 2, 3, 4, 5]
console.log(arr.map(e => e > 3))  // [false, false, false, true, true] 리턴
console.log(arr.map(e => e ** 2))  // [1, 4, 9, 16, 25] 리턴

console.log(arr.map(e => [e ** 2]))  // [[1], [4], [9], [16], [25]] 리턴
console.log(arr.flatMap(e => [e ** 2]))  // [1, 4, 9, 16, 25] 리턴

 

filter(element, index)

입력받은 조건 기준으로 입력받은 배열을 필터링하여 리턴

희소배열이나 false나 null 값을 갖는 요소를 제거하는 데 유용

let arr = [1, 2, 3, 4, 5]
console.log(arr.filter(e => e > 3))  // [4, 5] 리턴

 

every(element, index)

입력받은 조건 기준으로 입력받은 배열의 모든 요소가 조건을 만족하면 True 반환

let arr = [1, 2, 3, 4, 5]
console.log(arr.every(e => e > 3))  // False 리턴

 

some(element, index)

입력받은 조건 기준으로 입력받은 배열의 일부 요소만 조건을 만족해도 True 반환

let arr = [1, 2, 3, 4, 5]
console.log(arr.some(e => e > 3))  // True 리턴

 

reduce(accumulator, initialValue)

가산기처럼 사용할 수 있는 함수

빈 배열에 사용하면 초기값이 없다는 에러가 발생 → 초기값을 할당하여 해결

let arr = [1, 2, 3, 4 ,5]
console.log(arr.reduce((acc, e) => acc + e))  // 15 반환

let emptyArr = []
console.log(emptyArr.reduce((acc, e) => acc + e))  // 오류 발생!
console.log(emptyArr.reduce((acc, e) => acc + e, 0))  // 오류 X, 0 반환

- accumulator : 콜백의 반환값을 누적, 첫 번째 호출일 경우에는 첫 번째 인수의 값을 가짐

- initialValue : 초기값이 주어진 경우에는 인덱스 0, 기본값은 인덱스 1부터 시작

 

bind(Object)

함수와 객체를 서로 묶어주는 용도로 사용

함수 내에서 this.변수명 형태로 사용하는 경우, 해당 함수와 객체를 bind하여 this가 소실되는 것을 막는 역할

const kmj = { name: '미정', age: 25, job: '개발자' }
let hello = function() { console.log(this.name + ", hello!") }
hello()  // 콘솔에 ", hello!" 출력

hello = hello.bind(kmj)
hello()  // 콘솔에 "미정, hello!" 출력

 

find(element, index) / findIndex(element, index)

입력받은 배열에서 조건을 처음으로 만족하는 배열의 요소/인덱스 리턴

let arr = [1, 2, 3, 4, 5]
console.log(arr.find(e => e > 3))  // 4 리턴
console.log(arr.findIndex(e => e > 3))  // 4 리턴

 

템플릿 리터럴(Templete Literal)

백틱(`)을 사용하여 더하기 연산자보다 편리한 문자열 포맷팅 가능

const name = "미정", job = "개발자"

//console.log(name + "이는 " + job + "이다.")
console.log(`${name}이는 ${job}이다.`)

 

배열 및 객체 비구조화

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

const kmj = {
   name: '미정', age: 25, location: 'seoul'
}

let { name, age, location } = kmj  // 변수명은 key값과 같아야 함
console.log(name, age, location)  // 미정 25 seoul 리턴

 

Spread 연산자(...)

배열을 연결(concat)하거나 여러 변수들을 한 번에 받을 때(변수 목록을 생략할 때) 사용

배열을 destructuring 할 때도 사용

// 배열 concat
const arr = [1, 2, 3]
const arr2 = [...arr, 4, 5]
console.log(arr2)  // [1, 2, 3, 4, 5] 리턴

// 변수 목록 생략
const [a, b, ...c] = [1, 2, 3, 4, 5]
console.log(a, b, c)  // a = 1, b = 2, c = [3, 4, 5] 리턴

// 배열을 연속적인 요소처럼 처리
const sum = nList => (a, b, c) => a + b + c
const nList = [1, 2, 3]
console.log(sum(...nList))  // 15 리턴

 

padStart(n), padEnd(n)

문자열의 앞, 뒤로 패딩을 추가할 때 사용

문자열 길이 + 추가할 패딩 길이만큼 n을 전달

let str = "미정이"
console.log(str.padStart(10))
console.log(str.padEnd(10))

 

trimStart(), trimEnd()

문자열의 앞, 뒤로 패딩을 삭제할 때 사용

앞/뒤로 패딩을 한 번에 제거하고 싶다면 trim()을 사용하면 됨

let str = "       미정이"
console.log(str.trimStart())  // "미정이" 리턴

 

repeat(n)

입력받은 문자열을 n회 반복

let str = "*".repeat(10)
console.log(str)  // **********

 

Object keys, values, entries

Object 객체의 키와 값, [키, 값] 쌍을 리턴

const kmj = {
   name: '미정', age: 25, location: 'seoul'
}

console.log(Object.keys(kmj))  // ["name", "age", "location"] 반환
console.log(Object.values(kmj))  // ["미정", 25, "seoul"] 반환
console.log(Object.entries(kmj))  // [["name", "미정"], ["age", 25], ["location", "seoul"]] 반환

 

startsWith() / endswith()

해당 매개변수로 시작하는 / 끝나는지에 대한 여부를 True / False로 출력

let str = "wastfg6972@naver.com"
console.log(str.startsWith('was'))  // True

 

중첩배열 삭제(flat)

let arr = [1, 2, 3, [4, 5]]
console.log(arr.flat())  // [1, 2, 3, 4, 5] 반환

 

Value Shorthands

가져오려는 변수명과 그 값을 담기 위한 변수명을 동일하게 작성할 경우, : 생략 가능

const name = '미정', location = 'seoul'
const kmj = {
   name, age: 25, location
}

 

변수 Swapping

배열을 이용하여 변수 값을 서로 바꿀 수 있음

let a = 1, b = 10
[a, b] = [b, a]
console.log(a, b)  // 10 1 반환

 

변수 Skipping

배열에서 콤마(,)을 이용하여 특정 값 생략 가능

const days = ['sun', 'mon', 'tue', 'thu', 'fri']
const [a, , , , b] = days  // sun, fri만 선언 가능
console.log(a, b)  // sun fri 출력

 

Array 관련 메소드

- Array.of(...Element)

입력한 요소들을 유사 배열로 반환, iterable하지 않으므로 forEach 사용 불가

let arr = Array.of(1, 2, 3, 4, 5)
console.log(arr)  // 1, 2, 3, 4, 5 반환

 

- Array.from(Object)

입력한 요소를 배열로 반환

주로 document.getElementsByClassName() 등으로 받아온 iterable하게 사용하고자 할 때 사용하거나 배열을 복사할 때 사용

const btnList = document.getElementsByClassName('ico-btn')
btnList.onclick = () => { ... }

 

클래스(class) 선언 및 사용

class Person {
   constructor(name, age, job = '무직 백수') {
      this.name = name
      this.age = age
      this.job = job
   }
   print = () => console.log(this.name, this.age, this.job)
   get name = () => this.name
   get age= () => this.age
   get job = () => this.job
   set job = job => { this.job = job }
}


const kmj = new Person('미정', 25)
kmj.job('개발자')

kmj.print()

- get 변수명으로 getter 메소드를 만들 수 있음

- set 변수명으로 setter 메소드를 만들 수 있음

 

모듈 import / export

/* 모듈 Export */
// CommonJS 문법
module.exports = ...  // 모듈 생성
module.exports.메소드 = ...  // 모듈 안에 있는 메소드 생성

// ES6 문법
export { 내보낼 모듈1, 모듈2, 변수, 객체 }  // 여러 모듈 내보낼 때

export default 내보낼 모듈명  // 단일 모듈 내보낼 때

/* 모듈 Import */
// CommonJS 문법
const 모듈명 = require('모듈 경로')

// ES6 문법
import 모듈명 from '모듈 경로'  // 단일 모듈(default) 가져올 때
import { 가져올 모듈명, ... } from '모듈 경로'  // 가져올 애들 명시import * as '사용할 alias' from '모듈 경로'  // 모든 모듈을 묶어서 alias를 붙여줌

// html에서 사용
<script type="module" src="모듈 경로"></script>

만약 ES6 문법을 사용하다가 오류가 났다면 package.json 파일 안에 "type": "module"을 추가하면 오류가 해결된다.

package.json

 

 

async / await

async는 비동기 함수 생성 키워드 / await는 Promise의 then같은 역할(async로 선언된 함수 내에서만 사용 가능)

Promise와 같은 맥락으로 사용 가능

함수가 정상 실행 완료되면 resolve 상태의 Promise 객체 반환함수 실행 중 오류가 발생하면 reject 상태의 Promise 객체 반환

const waitFunc = async () => console.log('실행중...')  // Promise 객체 반환
waitFunc().then(() => console.log('끝!'))  // 실행중... 이후 끝! 출력

const resultFunc = async () => {
   console.log('실행 시작')
   await () => new Promise((resolve, reject) => resolve("완료된 Promise 객체 리턴"))
   console.log('실행 완료 후 뜨는 메시지')

}
const resultFunc = async () => {
   console.log('실행 시작')
   await function() { return new Promise((resolve, reject) => resolve("완료된 Promise 객체 리턴")) }
   console.log('실행 완료 후 뜨는 메시지')
}

resultFunc()  // 실행 시작 이후 실행 완료 후 뜨는 메시지 출력

 

Promise 객체

주로 비동기 작업에서 사용되는 패턴으로, 순차적인 코드 진행과 예외처리에 특화됨

pending(대기), fulfilled(이행완료), rejected(이행미완료), settled(결론)의 네 가지 상태를 가짐

// Promise 객체 예시
new Promise((resolve, reject) => {
  resolve(매개값)
  reject(매개값)
})
.then((매개값) => {
   // Promise 객체 내에서 resolve() 호출 시, then()으로 이동
})
.catch((매개값) => {
   // Promise 객체 내에서 reject() 호출 시, catch()으로 이동   // 예외처리에 사용
}).finally((매개값) => {    // 결과에 상관 없이 실행})

 

toString(n)

입력받은 10진수 숫자를 n진수 형태 문자열로 반환

let num = 123
console.log(num.toString(16))  // 7b
console.log(num.toString(8))  // 123
console.log(num.toString(2))  // 1111011

 

Iterator / Generator

Iterator는 forEach, map처럼 iterable한 iterable한 객체를 순회할 수 있으며, next 메소드를 실행할 때마다 다음 요소 반환

[Symbol.iterator]를 함수 앞에 붙여서 선언

next 메소드를 통해 { value, done } 객체를 반환

 

GeneratorIterator를 발생시키는 함수

function* 키워드로 생성하여 사용

function * gen() {
   yield 1
   yield 2
   yield 3
}
for (e of gen()) { console.log(e) }  // 순서대로 1, 2, 3 출력

 

거듭제곱(**)

console.log(2 ** 5)  // 32

 

- 그 외.... (시간 나면 더 정리해서 올릴게요!)

Atomics, globalThis, dynamic import, bigint, Proxy, SharedArrayBuffer, Symbol, allSettled, matchAll 등

 


ES12에서 추가된 메소드

일부 낮은 js 버전에서는 제공되지 않으므로 주의!

 

- replaceAll(param1, param2)

: 파라미터 1에 해당하는 문자열을 모두 파라미터 2로 변경

let str = 'i love you'
console.log(str.replaceAll(' ', ''))  // iloveyou

 

- Promise.any()

: 여러 개의 Promise 객체 중, 하나라도 resolve()가 실행되면 결과를 반환

const promise = n => new Promise((resolve) =>{
   setTimeout(() =>resolve(`${n} 초 경과 후 실행`), n*1000)
})

Promise.any([promise(4), promise(2), promise(6)]).then(e =>console.log(e))

 

- 숫자 구분자(_)

: 숫자를 알아보기 쉽게 언더바(_)를 넣어서 써도 됨

let n = 10_000  // 10000으로 인식

 

- WeakRef

: 가능한 사용하지 않는 것이 좋음

 

- 논리 할당 연산자(||=, &&=, ??=)

let nm = 'mj'
let name = '미정'
let boolean = false

// ||= : 왼쪽 값이 참이면 유지, 거짓이면 오른쪽 값으로 할당
boolean ||= nm  // boolean의 값이 'mj'로 재할당

// &&= : 두 값이 모두 참이면 오른쪽 값으로 할당, 하나라도 거짓이면 유지
boolean = true
boolean &&= '미정'  // boolean의 값이 '미정'으로 재할당

// ??= : 왼쪽 값이 null이나 undefined일 경우 오른쪽 값으로 할당
boolean = null
boolean ??= '미정'  // boolean의 값이 '미정'으로 재할당

 

- class의 private 메소드와 필드

: # 기호를 앞에 붙여서 사용하면 private로 처리 → 클래스 내에서만 접근 가능

class Person {
   construnctor(name, age) {
      this.name = name
      this.age = age
   }
   #hello = () => console.log(this.name + ", hello!") 
}