tip-archive
tip-archive copied to clipboard
[Google I/O 2019] Whatโs new JavaScript?
[Google I/O 2019] Whatโs new JavaScript?
2019๋ ์๋ ์ด๊น์์ด Google I/O ํ์ฌ๊ฐ ์์์ต๋๋ค. ์ ์ตํ ์๋ง์ ์ธ์ ์ค Whatโs new in JavaScript? ์ ๋ฃ๊ณ ์ ๋ฆฌํด๋ดค์ต๋๋ค.
๊ตฌ๊ธ์ JavaScript์ ์คํ์ ์ ํ๋ Vendor ์ฌ ์ค ํ ํ์ฌ์ ๋๋ค. tc39๋ผ๋ ์์ํ์๋ ๋ง์ ๊ตฌ๊ธ ๊ฐ๋ฐ์๊ฐ ์๋ ๊ฒ์ผ๋ก ์๊ณ ์์ต๋๋ค. tc39 ์์ํ์์๋ ECMAScript๋ผ๊ณ ๋ถ๋ฆฌ๋ JavaScript์ ๋ช ์ธ(์คํ)๋ฅผ ์ ์ํฉ๋๋ค. ํ์ฌ๋ ์ฌ๋ฌ ์ ์๋ค์ด ์ฌ๋ผ์ ์๋๋ฐ์, tc39/proposals ์ ์ฅ์์์ ํ์ธํ ์ ์์ต๋๋ค.
๋ณด๋ค ์์ธํ JavaScript ์คํ์ด ์ ํด์ง๋ ๊ณผ์ ์ ์ํฌ์ข ๋์ ECMAScript์ TC39 ๊ธ์ ์ถ์ฒํฉ๋๋ค.
TL;DR
๋ฐ์์ ๋ถ๋ค์ ์ํด ์์ฝ ๋จผ์ ํฌ์ฒํฉ๋๋ค.
- Class fields
- public and private (#)
- String.mathAll()
- Large Number with underscore (_)
- 1000000 === 1_000_000
- Array.flat()
- Object.entries()
- globalThis
- Intl
- Intl.RelativeTimeFormat
- Intl.ListFormat
- Intl.ListFormat
- Intl.Locale
- Promise
- allSettled
- any
- etc
- Use await on the top-level
- Array.sort() is stable
์ง๊ธ๋ถํฐ ์๊ฐํ๋ ๋ชจ๋ ๊ธฐ๋ฅ ๋ฐ ๋ช ์ธ๋ค์ Chrome ๊ธฐ์ค ๊ตฌํ์ด ์๋ฃ๋์์ผ๋ฉฐ ํ ๋ธ๋ผ์ฐ์ ๋ฅผ ์ง์ํ๊ธฐ ์ํด์๋ ํด๋ฆฌํ์ด ํ์ํฉ๋๋ค.
Class fields
ECMAScript 5์์๋ถํฐ ์ถ๊ฐ๋๋ class ๋ฌธ๋ฒ์ field ์์ญ ๊ด๋ จ ๋ฌธ๋ฒ์ด ์ถ๊ฐ๋์ต๋๋ค. ์ด๋ฏธ private field์ ๋ํด์๋ proposal ๋จ๊ณ์์๋ถํฐ์ด์ผ๊ธฐ๊ฐ ๋ง์์ต๋๋ค.
๋ฉค๋ฒ ๋ณ์(ํด๋์ค ๋ด์์ ์ฌ์ฉํ๋ ๋ณ์)์ private
์์ ๋ช
์ํ๊ธฐ ์ํด ์๋ฐ์คํฌ๋ฆฝํธ ๊ฐ๋ฐ์๋ค์ ์๋ฌต์ ์ผ๋ก ์์ underscore(_)๋ฅผ ์ถ๊ฐํ๊ณค ํ์ต๋๋ค. ๋ฌผ๋ก ์ฝ๋ ์์ผ๋ก๋ ์๋ฌด ์์ฉ์๋ convention์ ๋ถ๊ณผํฉ๋๋ค. TypeScript๋ฅผ ๋น๋กฏํ ๋ค๋ฅธ ์ธ์ด์์๋ ๋๋ถ๋ถ private
์ด๋ผ๋ reserved keyword๋ฅผ ํตํด ํด๋์ค ๋ด์์๋ง ์ ๊ทผํ ์ ์๋ private member variable์ ์ ์ํ์ง๋ง JavaScript์์๋ #
์ ์ฌ์ฉํ์ฌ ์ ์ํ๋๋ก ์คํ์ด ๊ตฌํ๋์ต๋๋ค.
AS-IS
class IncreasingCounter {
constructor() {
this._count = 0;
}
get value() {
return this._count;
}
}
const counter = new IncreasingCounter()
console.log(counter._count) // 0
TO-BE
public member variable
class IncreasingCounter {
counter = 0;
get value() {
return this.count;
}
}
private member variable
class IncreasingCounter {
#count = 0;
get value() {
return this.count;
}
}
const counter = new IncreasingCounter()
counter.count // Syntax Error
Node ๋ฐํ์ ํ๊ฒฝ์์๋ LTS version์๋ ์ด๋ฏธ ๊ตฌํ์ด ์๋ฃ๋ ์คํ์ ๋๋ค. (๐ข)
String.matchAll
์ด๋ฏธ ์ ๊ทํํ์์ ์ํ match API๋ ๊ตฌํ์ด ๋์ด์์์ต๋๋ค. ์ด matchAll
API๋ capturing group์ ํจ๊ป ๋ฐํํฉ๋๋ค.
AS-IS
const longString = 'Magic hex number: DEFAD CAFE'
const regex = '/\b\p{ASCII_Hex_Digit}+\b/gu'
for (const match of string.match(regex)) {
console.log(match)
}
// => Output
// 'DEFAD'
// 'CAFE'
TO-BE
const longString = 'Magic hex number: DEFAD CAFE'
const regex = '/\b\p{ASCII_Hex_Digit}+\b/gu'
for (const match of string.matchAll(regex)) {
console.log(match)
}
// => Output
// ['DEFAD', index: 19, input: '...']
// ['CAFE', index: 19, input: '...']
Large numeric value
ํฐ ์ ์์ ๊ฐ๋
์ฑ์ ๋์ด๊ธฐ ์ํด ์ถ๊ฐ๋ ์ซ์ ํ์์
๋๋ค. ์ธ ์๋ฆฌ ์๋ง๋ค _
๋ฅผ ํตํด ๊ตฌ๋ถ์ง์ ์ ์์ต๋๋ค.
10000000 => 10_000_000
์ญ์ babel์ ํ๋ฌ๊ทธ์ธ์ ํตํด ์ฌ์ฉํ ์ ์์ต๋๋ค.
BigInt
JavaScript๊ฐ ํธ๋ค๋ง ํ ์ ์๋ ์ ์์ ๋ฒ์๋ณด๋ค ํฐ ์ ์๋ฅผ ๋ค๋ฃฐ ๋ BigInt๊ฐ ์ถ๊ฐ๋์ต๋๋ค.
1234567890123456789 * 123
// 151851850485185200000 -> Not correct!
BigInt(1234567890123456789) * 123n
//151851850485185182464n
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/BigInt
Array.flat / Infinity
์ด API๋ ์ฌ๊ฑด์ด ์์์ต๋๋ค. ์ผ๋ช
SmoothGate. flat
API ์ด๋ฆ์ด smoosh
๋ก ์คํดํ(?) ์ฌ๊ฑด์
๋๋ค. ๊ด๋ จ ๋ด์ฉ์ ๊ตฌ๊ธ์ด ์ ๋ฆฌํด๋ ์๋ฃ๊ฐ ์์ด ์ฒจ๋ถํฉ๋๋ค. (#smooshgate FAQ)
flat
API๋ ์ค์ฒฉ๋ ๋ฐฐ์ด์ โํํํ๊ฒโ ํ ์ ์๋ API์
๋๋ค. ๊ธฐ์กด์๋ ๋ง์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์์๋๋ฐ์, ์ด๋ฒ์ ์คํ์ผ๋ก ํฌํจ๋์ต๋๋ค.
// Flatten one level
const array = [1, [2, [3]]]
array.flat()
// -> [1, 2, [3]]
array.flat(Infinity)
// -> [1, 2, 3]
Object.entries()
iterable ํ [key, value]๋ฅผ ๋ฐํํ๋ API์
๋๋ค. enumerable ์์ฑ์ ๋ํ์ฌ ๋ฐํํ๋ฉฐ ์์๋ object์ ๋ช
์๋ ๊ทธ ์์์ ๋์ผํฉ๋๋ค. ์ด API๋ฅผ ์ฌ์ฉํ์ฌ object๋ฅผ Map
์๋ฃ๊ตฌ์กฐ๋ก ์ฝ๊ฒ ๋ณํํ ์ ์๊ฒ ๋์ต๋๋ค. ๋ฐ๋์ API๋ก fromEntries()
API๋ ์กด์ฌํฉ๋๋ค.
const object = { lang: 'JavaScript', coolness: 9001 }
// Convert the object into a map
const map = new Map(Object.entries(object))
// Convet map into a object
const reObject = Object.fromEntries(map)
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/entries https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries
globalThis
JavaScript ๊ฐ๋ฐ์๊ฐ ์ ์ธ๊ณ์ ์ผ๋ก ์ ๋ง ๋ง๋ค๋ณด๋ ์ด ์คํ๋ ๋ ผ์๊ฐ ๋ง์์ต๋๋ค.
JavaScript์์ this
๋ ๊ณจ์นซ๊ฑฐ๋ฆฌ๋ก ์ ๋ช
ํ๋ฐ์, ๋ธ๋ผ์ฐ์ ์ธ์ง node.js ํ๊ฒฝ์ธ์ง์ ๋ฐ๋ผ์ ๊ทธ ๋์์ด ๋ฐ๋๊ธฐ ๋๋ฌธ์
๋๋ค. ์ด๋ฌํ ์ด์๋ก ์ฌ๋ฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์์๊ณ ํด๋ฆฌํ๋ ์์์ต๋๋ค. ์ด๋ฌํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ์์ ์ ์ญ this ๋ฅผ ์ ๊ณตํ๋ ์คํ์
๋๋ค.
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/globalThis
Intl
Intl.RelativeTimeFormat
const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' }); // 'ko' is available
rft.format(-1, 'day') // yesterday
rft.format(0, 'day') // today
rft.format(1, 'day') // tomorrow
Intl.ListFormat
const lfEnglish = new Intl.ListFormat('en', { type: 'disjunction'} );
lfEnglish.format(['a', 'b']) // 'a or b'
Intl.DateTimeFormat
const fmt = new Intl.DateTimeFormat('en', {
year: 'numeric'
month: 'long'
day: 'numeric'
});
const output = fmt.formatRange(date1, date2)
// 'May 7 - 9, 2019'
Intl
์ ์ด์ธ์๋ ์ฌ๋ฌ API๊ฐ ์์ต๋๋ค.
Promise
๊ธฐ์กด์๋ ์ ์ฉํ ๋ API(Promise.all, Promise.race)๊ฐ ์กด์ฌํ์ต๋๋ค. ์ฌ๊ธฐ์ ๋ค์ ๋ API๊ฐ ์ถ๊ฐ๋์ต๋๋ค. ์ ๋ง ์ฝ๊ฒ ํ์ด์จ๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์ API๊ฐ ๋ฉ๋๋ค.
+Promise.allSettled
์คํจ(rejected)๋ ์ฑ๊ณต(settled)์ด๋ ๋ชจ๋ ๊ฒ ๋ค ๋๋ ๋.
+Promise.any
์คํจ(rejected)๋ ์ฑ๊ณต(settled)์ด๋ ๊ฐ์ฅ ๋น ๋ฅธ ์ด๋ค ๊ฒ ํ๋๊ฐ ๋๋ ๋.
ETC
- Can use await function on the top-level without async function wrapping
early implemented.
- https://github.com/tc39/proposal-top-level-await
-
Array.sort()
is stable
๋ง๋ฌด๋ฆฌ
์ถ๊ฐ๋๋ JavaScript ์คํ์ ์์๋ดค์ต๋๋ค.
์ฌ๋ด.
์ฌ๋ผ์ด๋์ Angular๋ ์ด๋๊ฐ๊ณ React๊ฐ...๐คญ