프로그래밍/JavaScript

What’s new in JavaScript (Google I/O ’19) 정리

seungdols 2019. 5. 10. 21:14
  • numeric separators
  • BigInt
  • class fields
  • String#matchAll
  • Array#{flat, flatMap}
  • Object.fromEntries
  • globalThis
  • more Intl.* APIs
  • top-level await
  • Promise.{allSettled, any}
  • WeakRef

위와 같은 기능들이 추가 되었고, 모던 브라우저에서는 지원하는 기능도 있고, 아닌 기능도 있다. 그런데, 유용한 기능들이 있어서 정리를 해보고자 한다.

class fields

const counter = new IncreasingCounter(); 
counter.value;
counter.increment();
counter.value;

// ES2015+ 
class IncreasingCounter {
  constructor() {
    this._count = 0; 
  }
  get value() {
    console.log('Getting the current value!')
    return this._count;
  }
  increment() {
    this._count++;
  }
}

// simplify the class definition
class IncreasingCounter {
  _count = 0; 
  get value() {
    console.log('Getting the current value!')
    return this._count;
  }
  increment() {
    this._count++;
  }
}

// private field `#`
class IncreasingCounter {
  #count = 0; 
  get value() {
    console.log('Getting the current value!')
    return this.#count;
  }
  increment() {
    this.#count++;
  }
}

그렇지만, 위와 같은 기능은 Node.js, Chrome에서만 지원합니다.

string.matchAll

const regexp = /(seungdols(\d?))/g;
const str = 'seungdols1company/test1seungdols2';

// past 
for (const match of str.match(regexp)) {
  console.log(match)
}

// matchAll
const array = [...str.matchAll(regexp)];

console.log(array[0]);
// > Array ["seungdols1", "seungdols1", "1"]
console.log(array[1]);
// > Array ["seungdols2", "seungdols2", "2"]

위의 기능은 Chrome, Firefox, Node.js에서 지원합니다.

Improved numeric literals

1000000000000000
101011279793234.42

위와 같은 숫자는 몇인지 읽기가 어렵습니다. 그래서 제안 된 방법이 _ 를 사용하는 방법인데, grouping을 하는 겁니다.

1_000_000_000_000_000
101_011_279_793_234.42

대신 위의 기능은 chrome에서만 지원이 되며, chrome 75버전에서 사용이 가능합니다.

BigInt

1234567890123456789 * 123; 
// 151851850485185200000 -> error of calculation
1234567890123456789n * 123n
// 151851850485185185047n -> Ok.

위처럼 BigInt APIs는 Chrome, Firefox, Node.js에서 지원됩니다.

아래의 기능은 Chrome만 지원하지만, 아직 배포 전입니다.

151851850485185185047n.toLocaleString('en')

const numFormat = new Intl.NumberFormat('fr')
numFormat.format(151_851_850_485_185_185_047n)

Array.{flat, flatMap}

const arr = [1,[2,[3]]]

console.log(arr.flat()) // [1, 2, Array(1)]
console.log(arr.flat(Infinity)) //[1, 2, 3]

const duplicate = (x) => [x, x]
[2,3,4].map(duplicate) //[[2,2], [3,3], [4,4], [5,5]]
[2,3,4].map(duplicate).flat() //[2,2,3,3,4,4,5,5]
[2,3,4].flatMap(duplicate) //[2,2,3,3,4,4,5,5]

위의 기능은 Chrome, Firefox, safari, Node.js 모두 지원합니다.

Object.fromEntries

const object = { x: 29, y: 10 } 
const entries = Object.entries(object)
for (const [key, value] of entries) {
  console.log(`${key} is ${value}`)
}

const result = Object.fromEntries(entries) // {x: 29, y: 10}

위의 기능은 Chrome, Firefox, safari, Node.js 모두 지원합니다.

globalThis

const getGlobalThis = () => {
    if (typeof self !== 'undefined') return self;
  if (typeof window !== 'undefined') return window;
    if (typeof global !== 'undefined') return global;
  if (typeof this !== 'undefined') return this;
  throw new Error('Unable to locate global object')
}

const theGlobalThis = getGlobalThis(); 
// but doesn't work

const getThis = globalThis

위의 기능은 Chrome, Firefox, safari, Node.js 모두 지원합니다.

Stable sort

const cats = [
  { name: 'Naby', age: 4}, 
  { name: 'Mini', age: 6},
  { name: 'Hours', age: 8}
  { name: 'Hulu', age: 4}
]
cats.sort((a,b) => b.age - a.age)

위의 기능은 Chrome, Firefox, safari, Node.js 모두 지원합니다.

Intl.* APIs - Intl.RelativeTimeFormat

const rtf = new Intl.RelativeTimeFormat('en', {numeric: 'auto'})

rtf.format(-1, 'day') // yesterday
rtf.format(0, 'day') // today

new Intl.RelativeTimeFormat('ko', {numeric: 'auto'})
rtf.format(-1, 'day') // 어제

위의 기능은 Chrome, Firefox, Node.js 모두 지원합니다.

Intl.DateTimeFormat#formatRange

const start = new Date(startTimestamp)
const end = new Date(endTimestamp)
const fmt = new Intl.DateTimeFormat('en', {year: 'numeric', month: 'long', day: 'numeric'})

const output = fmt.formatRange(start, end)

Chrome은 지원 계획이다.

async/await

async function main() {
  const result = await doSomethings()
  doSomethinsElse()
}

main()

// IIFE
(async function main() {
  const result = await doSomethings()
  doSomethinsElse()
})()

// current
const result = await DoSomething
DoSomething()

Promise.* API

  • Promise.all
  • Promise.race
  • Promise.allSetteled
  • Promise.any

Chrome, Firefox만 지원이 된다.

WeakRef

function getImageById(id) {
  if (cache.get(id)) return cache.get(id) 
  const image = fetch(`/v1/products/image/${id}`)
     cache.set(id, image)
  return image
}


// use WeakRef
function getImageById(id) {
    let ref = cache.get(id)
  if (ref !== undefined) {
    let deref = ref.deref()
    if (deref !== undefined) return deref
  }
  const image = fetch(`/v1/products/image/${id}`)
  ref = new WeakRef(image)
     cache.set(id, ref) 
  return image
}

Garbage Collect의 대상이 쉽게 되도록 만들기 위함이다. 위 처럼 아주 잠깐 사용하고, Cache에 저장할 목적이라면, 해당 Object는 사실 캐싱 이후에는 빠르게 메모리에서 해제 되는 것이 메모리 사용률을 효율적으로 만들게 된다.

이 기능은 Chrome만 지원하며, 현재 아직 배포가 된 기능은 아니다.

반응형