ECMAScript 6
๋ ECMAScript ํ์ค์ ๊ฐ์ฅ ์ต์ ๋ฒ์ ๐ง ES6 ์๋ก์ด ๋ฌธ๋ฒ
1)
const
andlet
2)Arrow functions
(ํ์ดํ ํจ์)
3)Array and object destructing
(๋ฐฐ์ด ๋ฐ ๊ฐ์ฒด ๋น๊ตฌ์กฐํ ํ ๋น)
4)Default parameters
(๊ธฐ๋ณธ ๋งค๊ฐ ๋ณ์)
5)Template Literals
(ํ ํ๋ฆฟ ๋ฆฌํฐ๋ด)
6)Import
andexport
(๊ฐ์ ธ์ค๊ธฐ ๋ฐ ๋ด๋ณด๋ด๊ธฐ)
7)Promises
(ํ๋ก๋ฏธ์ค)
8)Rest parameter and Spread operator
(๋๋จธ์ง ๋งค๊ฐ ๋ณ์ ๋ฐ ํ์ฐ ์ฐ์ฐ์)
9)Classes
(ํด๋์ค)
var
vs let
vs const
var
: ES6 ์
๋ฐ์ดํธ ์ด์ ์ ๋ณ์ ํ ๋น๋ฐฉ์. ์์ ๋กญ๊ฒ ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ฉฐ function scope(ํจ์ ๋ฒ์)var name = "yyy";
console.log(name) // yyy
var name = "www";
console.log(name) // www
let
: ๋ณ์์ ์ฌํ ๋น์ด ๊ฐ๋ฅํ block scope(๋ธ๋ก ๋ฒ์).let
์ ๋ณ์๋ฅผ ์ ์ธํ ๋ธ๋ก๊ณผ ๊ทธ ๋ด๋ถ ๋ธ๋ก๋ค์์๋ง ์ ํจํ๋ค.let hello='first hello';
{
let hello = 'inner hello';
console.log(hello); // inner hello
}
console.log(hello); // first hello
const
: ๋ณ์ ์ฌ์ ์ธ, ์ฌํ ๋น ๋ชจ๋ ๋ถ๊ฐ๋ฅํ block scope (๋ฐฐ์ด๊ณผ ์ค๋ธ์ ํธ์ ๊ฐ์ ๋ณ๊ฒฝํ๋ ๊ฒ์ ๊ฐ๋ฅํจ)const hello='hello';
hello='change hello'; // ์ฌ ์ ์ ๋ถ๊ฐ
const hello='hello!';
{
const hello='inner hello!'; // ๋ธ๋ก ๋จ์ ์ค์ฝํ์ด๊ธฐ ๋๋ฌธ์ ์ ์ธ ๊ฐ๋ฅ
console.log(hello); // inner hello!
}
console.log(hello); // hello!
// ์์ ์ ์ธ์ ์
// ES5
var button = document.getElementById("button1");
// ES6
const button = document.getElementById("button2");
- ๋ธ๋ก๋ ๋ฒจ์ ์ค์ฝํ๋ฅผ ๊ฐ์ง
- ๊ฐ์ ์ค์ฝํ(
{ }
)์์ let ์ผ๋ก ๋ณ์๋ฅผ ์ฌ์ ์ ํ๋ ๊ฒ ๋ถ๊ฐ- let, const๋ ํธ์ด์คํ ์ ์ฉ์ด ์๋จ. ๋ณ์ ์ ์ธ ์ด์ ์ ์ ๊ทผ ๋ถ๊ฐ๋ฅํจ
๐ ๊ฐ์ ๋ฌธ์์ด์ธ์ง ํ์ธ ํ๋ ๋ฉ์๋ โก
startsWith
,endsWith
,includes
let str = "helloooo"; let matchstr = "hello //์์๊ฐ์ด ๊ฐ์์ง console.log(str.startsWith(matchstr)); //๋๊ฐ์ด ๊ฐ์์ง console.log(str.endsWith(matchstr)); //๋งค์นญ๋๋ ๋ฌธ์์ด์ด ์๋์ง console.log(str.includes(matchstr));
=>
๋ฌธ๋ฒ์ ์ฌ์ฉํ๋ ์ถ์ฝํ ํจ์ ์ด๋ค. (ํํ: (์ธ์) => ํจ์๋ณธ๋ฌธ
)()
์์ ํจ์์ ์ธ์๊ฐ ๋ค์ด๊ฐ๊ณ , =>
์ค๋ฅธ์ชฝ์๋ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๋ ์์ด๋ค.{ }
) ๋ณธ๋ฌธ(statement block bodies)๋ ์ง์ํ๋ค. let evens = [2, 4, 6, 8,];
// Expression bodies (ํํ์์ ๊ฒฐ๊ณผ๊ฐ ๋ฐํ๋จ)
let odds = evens.map(v => v + 1); // [3, 5, 7, 9]
let nums = evens.map((v, i) => v + i); // [2, 5, 8, 11]
let pairs = evens.map(v => ({even: v, odd: v + 1})); // [{even: 2, odd: 3}, ...]
// Statement bodies (๋ธ๋ญ ๋ด๋ถ๋ฅผ ์คํ๋ง ํจ, ๋ฐํ์ ์ํด์ return์ ๋ช
์ํด์ผํจ)
nums.forEach(v => {
if (v % 5 === 0)
fives.push(v);
});
// Lexical this
let bob = {
name: "Bob",
friends: ["John, Brian"],
printFriends() { // ํจ์ ๋ธ๋ญ ์์์ this๋ฅผ ์ฐธ์กฐ
this.friends.forEach(el =>
console.log(this.name + " knows " + el));
}
}
// ์ถ๋ ฅ๊ฒฐ๊ณผ : Bob knows John, Brian
1. ์ธ์๊ฐ ์์ ๋ ๋น ๊ดํธ ์ธํธ๊ฐ ํ์ํ๋ค.
2. ์ธ์๊ฐ 1๊ฐ์ผ ๋๋ ์๋ต์ด ๊ฐ๋ฅํ๋ค.
3. ํจ์๊ฐ ๊ฐ์ฒด ๋ฆฌํฐ๋ด์ ๋ฐํํ๋ ๊ฒฝ์ฐ ๊ผญ () ๊ดํธ๋ก ๊ฐ์ธ์ผ ํ๋ค.
4. ๋ช ๋ น ๊ตฌ๋ถ์ผ๋ก ์ด๋ค์ ธ ์๊ณ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํด์ผํ ๋ {} ๊ดํธ๊ฐ ํ์ํ๋ค.// 1. ์ธ์๊ฐ ์์ ๋ ๋น ๊ดํธ ์ธํธ๊ฐ ํ์ํ๋ค. var countFruits = () => fruits.length; // ES5 var countFruits = function () { return fruits.length; } // 2. ์ธ์๊ฐ 1๊ฐ์ผ ๋๋ ์๋ต์ด ๊ฐ๋ฅํ๋ค. var filteredFruit = fruits.filter(fruits => fruits.price > 100); // ๊ณผ์ผ ๊ฐ๊ฒฉ์ด 100 ๋๋ ๊ฒ๋ง ๊ณจ๋ผ์ ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด์ค console.log(filteredFruit); // [{name: "banana", price: 120}] // ES5 fruits.filter(function (fruit) { return fruit.price > 100; }); // 3. ํจ์๊ฐ ๊ฐ์ฒด ๋ฆฌํฐ๋ด์ ๋ฐํํ๋ ๊ฒฝ์ฐ ๊ผญ () ๊ดํธ๋ก ๊ฐ์ธ์ผ ํ๋ค. var inventory = fruits.map(fruit => ({name:fruit.name, storage: 1})); // ๊ณผ์ผ์ ๋ฐ์๋ค๊ฐ {name:fruit.name, storage: 1} ํํ๋ก ๋ณํํ ๋ฆฌ์คํธ ๊ฐ์ฒด๋ฅผ ๋ฐํ console.log(inventory); // [{name: "apple", storage: 1}, {name: "orange", storage: 1}, {name: "banana", storage: 1}] // ES5 var inventory = fruits.map( function (fruit) { return { name: fruit.name, storage: 1 } }); // 4. ๋ช ๋ น ๊ตฌ๋ถ์ผ๋ก ์ด๋ค์ ธ ์๊ณ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํด์ผํ ๋ {} ๊ดํธ๊ฐ ํ์ํ๋ค. var inventory = fruits.map(fruit => { console.log('checking ' + fruit.name + ' storage'); return { name: fruit.name, storage : 1}; }); // ES5 var inventory = fruits.map(function(fruit) { console.log('checking ' + fruit.name + ' storage'); return { name: fruit.name, storage : 1}; });
๋ฐฐ์ด
๊ณผ ๊ฐ์ฒด
์ ํจํด ๋งค์นญ์ ํตํ ๋ฐ์ดํฐ ๋ฐ์ธ๋ฉ์ ์ ๊ณตํ๋ค.
- ๊ฐ์ฒด Destructuring
ES6์ ๊ฐ์ฒด Destructuring์๊ฐ์ฒด
๋ฅผ import ํ๊ฑฐ๋ ๊ฐ์ ธ๋ค ์ธ ๋ ์ํ๋ ๊ฐ์ฒด์ ํค ๊ฐ๋ง ์ฌ์ฉํ ์ ์๊ธฐ ๋๋ฌธ์ ๋ฉ๋ชจ๋ฆฌ ํจ์จ์ ์ข๋ค.// (1) ๊ธฐ์กด ๊ฐ์ฒด ํค๊ฐ์ ํด์ฒด(ES6์ ์ฝ๋) //๊ฐ์ฒด์ ์ธ const animals = { cat: 'CAT', dog: 'DOG', tiger: 'TIGER' } //๊ฐ๊ฐ๋ณ์๋ด๊ธฐ const cat = animals.cat; const dog = animals.dog; const tiger = animals.tiger; //๊ฐ๊ฐํธ์ถ console.log(cat); console.log(dog); console.log(tiger); // (2) ๋น๊ตฌ์กฐํ ํ ๋น๋ฐฉ์ ๊ฐ์ฒด ์ ์ธ ๋ฐ ํธ์ถ // ๋น๊ตฌ์กฐํ ๋น๋ฐฉ์์ ์ด์ฉํ๋ฉด 4์ค์ 1์ค ์ฝ๋๋ก ๋ณ๊ฒฝ ๊ฐ๋ฅ, ํจํด ๋งค์นญ์ ํตํ ๋ฐ์ดํฐ ๋ฐ์ธ๋ฉ์ ๊ฒฐ๊ณผ const { cat2, dog2, tiger2 } = { cat2: 'CAT', dog2: 'DOG', tiger2: 'TIGER' }; console.log(cat2); console.log(dog2); console.log(tiger2); // object matching let { first: a, second: { fourth: b }, third: c } // object matching ๋จ์ถ ํ๊ธฐ let {first, second, third} = getASTNode() // `first`, `second` and `third`๋ฅผ ํ๋์ ํจ์ scope์ ๋ฐ์ธ๋ฉํ๋ค // spread ๋ฌธ๋ฒ const { cat3, ...animals3 } = { cat3: 'CAT', dog3: 'DOG', tiger3: 'TIGER' }; console.log(cat3); // CAT console.log(animals3); // {dog3: 'DOG', tiger3: 'TIGER'}
- ๋ฐฐ์ด Destructuring
ES6์ ๋ฐฐ์ด Destructuring์๋ฐฐ์ด
์ ๊ฐ ์์๋ฅผ ๋ฐฐ์ด๋ก๋ถํฐ ์ถ์ถํ์ฌ ๋ณ์ ๋ฆฌ์คํธ์ ํ ๋นํ๋ค. ์ด๋ ์ถ์ถ/ํ ๋น ๊ธฐ์ค์ ๋ฐฐ์ด์ ์ธ๋ฑ์ค์ด๋ค.// (1) ๊ธฐ์กด ๋ฐฐ์ด ๊ฐ์ ํด์ฒด(ES6์ ์ฝ๋) const animalList = ['CAT', 'DOG', 'TIGER']; //๋ฐฐ์ด์ ์ธ //๊ฐ๊ฐ ๋ณ์๋ด๊ธฐ const cat = animalList[0]; const dog = animalList[1]; const tiger = animalList[2]; //๊ฐ๊ฐํธ์ถ console.log(cat); console.log(dog); console.log(tiger); // (2) ๋น๊ตฌ์กฐํ ํ ๋น๋ฐฉ์ ๋ฐฐ์ด ์ ์ธ ๋ฐ ํธ์ถ // ๋น๊ตฌ์กฐํ ๋น๋ฐฉ์์ ์ด์ฉํ๋ฉด 4์ค์ 1์ค ์ฝ๋๋ก ๋ณ๊ฒฝ ๊ฐ๋ฅ, ํจํด ๋งค์นญ์ ํตํ ๋ฐ์ดํฐ ๋ฐ์ธ๋ฉ์ ๊ฒฐ๊ณผ const [cat1, dog1, tiger1] = ['CAT', 'DOG', 'TIGER']; console.log(cat1); console.log(dog1); console.log(tiger1); // ๋ฐฐ์ด ๋์คํธ๋ญ์ฒ๋ง ์ฌ์ฉ์์ let x, y, z; [x, y] = [1, 2]; console.log(x, y); // 1 2 [x, y] = [1]; console.log(x, y); // 1 undefined [x, y] = [1, 2, 3]; console.log(x, y); // 1 2 [x, , z] = [1, 2, 3]; console.log(x, z); // 1 3 // ๊ธฐ๋ณธ๊ฐ [x, y, z = 3] = [1, 2]; console.log(x, y, z); // 1 2 3 // z์ ๊ธฐ๋ณธ๊ฐ์ ์ค์ ํด ์ค [x, y = 10, z = 3] = [1, 2]; console.log(x, y, z); // 1 2 3 // x,y์ ๋ํ ๊ธฐ๋ณธ๊ฐ์ด ์์ด๋ ์๋ก ์ง์ ๋ ๊ฐ์ ์ฐ์ (์ต๊ทผ) ์ ์ฉ // spread ๋ฌธ๋ฒ [x, ...y] = [1, 2, 3]; console.log(x, y); // 1 [ 2, 3 ] const animalList = ['CAT', 'DOG', 'TIGER']; const [cat2, ...restAnimalList] = animalLis; //์์ ์์ 1๊ฐ์ ๋๋จธ์ง ์์๋ฅผ ๋ถ๋ฆฌํ๊ณ ์ถ์ ๋ ์ ์์ ์ฝ๋์ฒ๋ผ ์ฌ์ฉ ๊ฐ๋ฅ console.log(cat); // CAT console.log(restAnimalList); // ["DOG", "TIGER"]
let ์๋ก์ด๊ฐ์ฒด๋ช
= {...๊ธฐ์กด๊ฐ์ฒด๋ช
};
let ์๋ก์ด๋ฐฐ์ด๋ช
= [...๊ธฐ์กด๋ฐฐ์ด๋ช
];
// Spread Operator ์์ ์ฝ๋
// obj ๊ฐ์ฒด๋ฅผ newObj ๊ฐ์ฒด์ ๋ณต์
let obj = {
a: 10,
b: 20
};
let newObj = {...obj};
console.log(newObj); // {a: 10, b: 20}
// arr ๋ฐฐ์ด์ newArr ๋ฐฐ์ด์ ๋ณต์
let arr = [1,2,3];
let newArr = [...arr];
console.log(newArr); // [1, 2, 3]
ES6์์ class ๋ผ๋ ๋ฌธ๋ฒ์ด ์ถ๊ฐ ๋์๊ณ , ๊ธฐ์กด์ prototype ๊ธฐ๋ฐ์ผ๋ก ํด๋์ค๋ฅผ ๋ง๋๋ ๊ฒ๋ณด๋ค ๋ช ๋ฃํ๊ฒ ํด๋์ค๋ฅผ ๋ง๋ค ์ ์๊ฒ ๋์๋ค.
// ํด๋์ค ์ ์ธ(Class declarations) class Polygon { constructor(height, width) { this.height = height; this.width = width; } }
โ ํด๋์ค ์ ์ธ์ ํจ์ ์ ์ธ๊ณผ ๋ฌ๋ฆฌ ํธ์ด์คํ ๋์ง ์๋๋ค.
var p = new Polygon(); // Reference Error class Polygon {} // ํด๋์ค๊ฐ ์ ์(์ ์ธ)๋๊ธฐ ์ ์ ์ธ์คํด์ค๋ฅผ ๋จผ์ ์ ์ํ๋ฉด error
//ํด๋์ค ํํ(Class expressions) โก ์ต๋ช ํด๋์ค์ ๊ธฐ๋ช ํด๋์ค๋ฅผ ๋ง๋ค ์ ์๋ค. // unnamed var Polygon = class { constructor(height, width) { this.height = height; this.width = width; } }; // named var Polygon = class Polygon { constructor(height, width) { this.height = height; this.width = width; } };
โ ํด๋์ค ํํ(Class expressions) ๋ํ ํด๋์ค ์ ์ธ(Class declarations)์ ๊ฐ์ด
ํธ์ด์คํ (hoisting)์ด ๋์ง ์๋๋ค.
๐ฅ ์์ฑ์(Constructor)
์์ฑ์ ๋ฉ์๋๋ ๊ฐ์ฒด์ ์์ฑ๊ณผ ์ด๊ธฐํ๋ฅผ ํ๋ ํน๋ณํ ๋ฉ์๋์ด๋ค. ํด๋์ค์์ constructor ์ด๋ฆ์ ๊ฐ๋ ๋ฉ์๋๋ ํ๋์ฌ์ผ ํ๋ค.
// constructor๊ฐ 2๊ฐ์ด๊ธฐ ๋๋ฌธ์ ERROR!!! var Polygon = class { constructor(height, width) { this.height = height; this.width = width; } constructor(height2, width2) { this.height = height2 * 2 ; this.width = width2 * 2; } };
๐ฅ super ํค์๋
์์ฑ์ ๋ฉ์๋์์ super ํค์๋๋ฅผ ํตํด ์์ ํด๋์ค์ ์์ฑ์ ๋ฉ์๋๋ฅผ ํธ์ถ ํ ์ ์๋ค.
class Polygon { constructor(height, width) { this.height = height; this.width = width; } } class Square extends Polygon { constructor(length) { // length๋ก ๋ค๊ฐํ์ ๋์ด์ ๋์ด๋ฅผ ์ ์ํ๊ธฐ ์ํด ๋ถ๋ชจํด๋์ค์ ์์ฑ์๋ฅผ ํธ์ถ. super(length, length); // Note: ํ์ ํด๋์ค์์, 'this'๋ฅผ ์ฌ์ฉํ๊ธฐ ์ ์๋ ๋ฐ๋์ super()๋ฅผ ํธ์ถํด์ผํ๋ค. // ๊ทธ๋ ์ง ์์ ๊ฒฝ์ฐ ์ฐธ์กฐ์๋ฌ๊ฐ ๋ฐ์. this.name = 'Square'; } get area() { return this.height * this.width; } set area(value) { this.area = value; } } var test = new Square(4); console.log(test.area); // ์์ฑ์ ๋ฉ์๋์์ this๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์ super ๋ฉ์๋๋ฅผ ๋จผ์ ํธ์ถํด์ผ ํ๋ค!!!
๐ฅ ํด๋์ค ์์(sub classing)
extends
ํค์๋๋ฅผ ํตํ์ฌ ํด๋์ค๋ฅผ ์์ ๋ฐ์, ์์ ํด๋์ค๋ฅผ ๋ง๋ค ์ ์๋ค.
// ES6์ ํด๋์ค ์์ class Animal { constructor(name) { this.name = name; } speak() { console.log(this.name + ' makes a noise.'); } } class Dog extends Animal { // Animal์ ์์๋ฐ์์ Dog๋ผ๋ ์์ ํด๋์ค์์ฑ speak() { console.log(this.name + ' barks.'); } } var d = new Dog('Mitzie'); d.speak();
cf) ํ๋กํ ํ์
๊ธฐ๋ฐ์ ํด๋์ค ์์
ํ๋กํ ํ์
๊ธฐ๋ฐ์ ํด๋์ค๋ extends ํค์๋๋ฅผ ํตํด ์์ ํ ์ ์๋ค.
// ํ๋กํ ํ์ ๊ธฐ๋ฐ์ ํด๋์ค ์์ function Animal (name) { this.name = name; } Animal.prototype.speak = function () { console.log(this.name + ' makes a noise.'); } class Dog extends Animal { speak() { console.log(this.name + ' barks.'); } } var d = new Dog('Mitzie'); d.speak();
let obj = { // __proto__ __proto__: theProtoObj, // โhandler: handlerโ์ ๋จ์ถ ํ๊ธฐ handler, // Methods toString() { // Super calls return "d " + super.toString(); }, // Computed (dynamic) property names [ 'prop_' + (() => 42)() ]: 42 };
ํ๋ผ๋ฏธํฐ์ ๊ธฐ๋ณธ ๊ฐ์ ์ค์ ํ ์ ์๋ค.
function f(x, y=12) { // y๊ฐ์ด ๋ฐ๋ก ์ง์ ๋์ง ์๋๋ค๋ฉด ๊ธฐ๋ณธ๊ฐ 12์ด๋ค. return x + y; } f(3) // 15 ๊ฐ๋ณ์ธ์๋ฅผ ์ฌ์ฉ๊ฐ๋ฅํ๋ฉฐ, ๋ฐฐ์ด๋ก ์นํ์์ผ ์ค๋ค. Rest parameters๋ arguments ๋ณด๋ค ์ง๊ด์ฑ์ ์ ๊ณตํฉ๋๋ค. function f(x, ...y) { // y is an Array ["hello", true] return x * y.length; } f(3, "hello", true) // 6 ํจ์ ํธ์ถ ์ ๋ฐฐ์ด์ ์ผ๋ จ์ ์ธ์์ ๋๋์ด ์ฃผ์ ์์ผ ์ค๋ค. function f(x, y, z) { return x + y + z; } // Pass each elem of array as argument f(...[1,2,3]) // 6
Iterator ๊ฐ์ฒด
๋ ์ฌ์ฉ์ ์ ์์ ๋ฐ๋ณต์ ๊ฐ๋ฅํ๊ฒ ํด์ค๋ค. for..of
๋ฐ๋ณต๋ฌธ์ด ES6์์ ์ถ๊ฐ ๋์์ผ๋ฉฐ for..in ๋ฐ๋ณต๋ฌธ๊ณผ ๋ฌ๋ฆฌ iterator ๊ธฐ๋ฐ์ ์ปฌ๋ ์
์ ์ฉ ๋ฐ๋ณต๋ฌธ์ด๋ค.
for (variable of iterable) { statement } const array123 = ['a', 'b', 'c']; for (const element of array123) { console.log(element); } // expected output: "a" // expected output: "b" // expected output: "c"
// Basic literal string creation `In JavaScript '\n' is a line-feed.` // Multiline strings `In JavaScript this is not legal.` // String interpolation var name = "Bob", time = "today"; `Hello ${name}, how are you ${time}?` // Construct an HTTP request prefix is used to interpret the replacements and construction POST`http://foo.org/bar?a=${a}&b=${b} Content-Type: application/json X-Credentials: ${credentials} { "foo": ${foo}, "bar": ${bar}}`(myOnReadyStateChangeHandler);
// same as ES5.1
"๐ ฎท".length == 2
// new RegExp behaviour, opt-in โuโ
"๐ ฎท".match(/./u)[0].length == 2
// new form
"\u{20BB7}" == "๐ ฎท" == "\uD842\uDFB7"
// new String ops
"๐ ฎท".codePointAt(0) == 0x20BB7
// for-of iterates code points
for(var c of "๐ ฎท") {
console.log(c); // ๐ ฎท
}
2์ง๋ฒ (b), 8์ง๋ฒ (o) numeric ๋ฆฌํฐ๋ด ํ์์ด ์ถ๊ฐ๋์๋ค.
class Greeting {
constructor(name) {
this.name = name;
}
greet() {
return `Hello ${name}`;
}
}
function greetingFactory(name) {
return Reflect.construct(Greeting, [name], Greeting);
}
greetingFactory('a'); // Greeting {name: "a"}
๋ง์ง๋ง์ ํธ์ถ๋๋ ํจ์๊ฐ ํธ์ถ ์คํ์ด ์ด๊ณผ๋๊ฒ ํ์ง ์๋๋ค. ์ฌ๊ท ์๊ณ ๋ฆฌ์ฆ์ ๋งค์ฐ ํฐ ์ ๋ ฅ ๊ฐ์์๋ ์์ ํ๊ฒ ๋ง๋ ๋ค.
function factorial(n, acc = 1) {
'use strict';
if (n <= 1) return acc;
return factorial(n - 1, n * acc);
}
// ํ์ฌ ๋๋ถ๋ถ์ ์๋ฐ์คํฌ๋ฆฝํธ ์์ง์์ ์คํ ์ค๋ฒํ๋ก์ฐ๊ฐ ์ผ์ด๋์ง๋ง,
// ES6์์๋ ์
๋ ฅ ๊ฐ์ด ์ปค๋ ์์ ํ๋ค
factorial(100000);