ECMAScript 6๋ ECMAScript ํ์ค์ ๊ฐ์ฅ ์ต์ ๋ฒ์ ๐ง ES6 ์๋ก์ด ๋ฌธ๋ฒ
1)
constandlet
2)Arrow functions(ํ์ดํ ํจ์)
3)Array and object destructing(๋ฐฐ์ด ๋ฐ ๊ฐ์ฒด ๋น๊ตฌ์กฐํ ํ ๋น)
4)Default parameters(๊ธฐ๋ณธ ๋งค๊ฐ ๋ณ์)
5)Template Literals(ํ ํ๋ฆฟ ๋ฆฌํฐ๋ด)
6)Importandexport(๊ฐ์ ธ์ค๊ธฐ ๋ฐ ๋ด๋ณด๋ด๊ธฐ)
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,includeslet 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);