ECMAScript6's new array methods
ECMAScript6โs new array methods
1. Class methods
๋ฐฐ์ด์ ๊ทธ ์์ง์ ๋ฉ์๋๋ฅผ ์ป๋ ์ํ์ด๋ค.
1.1 Array.from(arrayLike, mapFunc?, thisArg?)
Array.from()์ ๊ธฐ๋ณธ ํจ์ํ ์ด๋ค ๋ฐ๊พผ๋ค ๋๊ฐ์ ๊ฐ์ฒด์ ์ข ๋ฅ ๋ฐฐ์ด์์ :
Array-like obejcts๋ ์๋ง๋ length์ elements์ ์ธ๋ฑ์ค๋ฅผ ๊ฐ์ง๊ณ ์๋ค. ์๋ฅผ ๋ค์ด ๋ถ๋ฌ์จ๋ค DOM ์ฐ์ฐ์์ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ๊ฐ document.getElementsByClassName()๋
Iterable object์ ์ปจํ ์ธ ๋ ๊ฒ์๋์ด ์ฌ ์ ์๋ค ํ๋์ element์์ ์ ์์. Arrays๋ iterable์ด๋ค, ECMAScriptโs์ ์๋ก์ด ๋ฐ์ดํฐ ๊ตฌ์กฐ Map๊ณผ Set.
๋ค์์ ์ฝ๋๋ ์์ ์ด๋ค ๋ฐ๊พธ๋ array-like ๊ฐ์ฒด์ ๋ฐฐ์ด์์:
let lis = document.querySelectorAll('ul.fancy li'); Array.from(lis).forEach(function (li) { console.log(node); });
querySelectorAll()์ ๊ฒฐ๊ณผ๋ ๋ฐฐ์ด์ด ์๋๊ณ , ๊ฐ์ง๊ณ ์์ง ์๋ค forEach()๋ฉ์๋๋ฅผ, ๊ทธ๊ฒ์ ์ด๋ค ์ ์ฐ๋ฆฌ๊ฐ ํ์ํ์ง ๋ฐ๊พธ๊ธฐ ์ํด ๊ทธ๊ฒ์ ๋ฐฐ์ด์์ ์ ์ ์ฐ๋ฆฌ๋ ์ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
Array.from์ ํ๋ฝํ๋ค. ๋น์ ์ด ์กฐ์ ํ๊ธฐ๋ฅผ ์์ฑ์ ๊ทธ๊ฒ์ ๊ทธ๊ฒ์ ๊ฒฐ๊ณผ๋ฅผ ์ํด ์ฌ์ฉํ๋. ์๋ฅผ ๋ค์ด ๋ง์ฝ์ ๋น์ ์ด ๋ง๋ค๊ณ ์๋ธํด๋์ค ๋ฐฐ์ด์ ์์ ๋ฐฐ์ด ๊ทธ๋ฆฌ๊ณ ์ํ๋ฉด ๋ฐ๊พธ๊ธธ ๋ช๊ฐ์ง array-like ๋๋ iterable์ ๊ทธ๊ฒ์ ๋์ ํด์, ๋น์ ์ ๋จ์ํ๊ฒ Myarray.from()๋ฅผ ์ฌ์ฉํ๋ค. ์ด์ ๋ ์ ๊ฒ์ ์ผํ๋ค ์์ฑ์๋ฅผ ์์ ๊ฐ๊ฐ ๋ค๋ฅธ ๊ณณ์์ ECMAScript6(์ํผ์์ฑ์๋ ์๋ธ ์์ฑ์์ ํ๋กํ ํ์ ์ด๋ค.)
class MyArray extends Array { ... } let instanceOfMyArray = MyArray.from(anIterable);
์ง๊ธ ์ฐ๋ฆฌ๋ ๋ณผ ์ ์๋ค ์ mapFunc์ ํ๋ผ๋ฏธํฐ๋ ํจ์จ์ ์ด๋ค: ๊ทธ๊ฒ์ Array.from()์ ๋ง๋ค๊ณ Array.prototype.map()์ ๋ณ์ข ๊ฒฐ๊ณผ๋ฅผ ์์ฐํ๊ณ ๊ทธ๊ฒ์ ์์ฑ์๋ ๋น์ ์ ๋ช ์ํ ์ ์๋ค(์์ฑ์๋ฅผ ํตํด from()์ ๋ถ๋ฌ์ค๋ค):
let instanceOfMyArray = MyArray.from([1, 2, 3], x => x * x); let instanceOfArray = [1, 2, 3].map(x => x * x);
๋ ๋ฉ์๋์ ํ๋ผ๋ฏธํฐ(๋ง์ง๋ง) arrow function์ด๋ค.
1.2 Array.of(โฆitems)
๋ง์ฝ ๋น์ ์ด ์ํ๋ฉด ๋์์ค๊ธธ ๋ช๊ฐ์ง ๊ฐ๋ค์ด ๋ฐฐ์ด์, ๋น์ ์ array literal์ ํญ์ ์ฌ์ฉํ๋ค, ํนํ array constructor์ ๊น์ง ์๋ง ์ผํ์ง ์๋๋ค ๋ง์ฝ์ ๊ฑฐ๊ธฐ์ ์ฑ๊ธ ๊ฐ์ด ์ซ์์ด๋ค ( ๋ ๋ง์ ์ ๋ณด๋ ๋ณ๋๋ค )
> new Array(3, 11, 8) [ 3, 11, 8 ] > new Array(3) [ , , ,] > new Array(3.1) RangeError: Invalid array length
๊ทธ๋ฌ๋ ์ด๋ป๊ฒ ์ง์๋์ด์ง๊น ๋น์ ์ ๋๋์ ์ค๋ ๋ฐฐ์ด์ sub-constructor๋ฅผ ๋์ ํ ๊ฐ๋ค? ์ด๊ฒ์ ์ด๋ค/Array.of()์ ๋์(๊ธฐ์ตํ์ ๋ฐฐ์ด ๋ฉ์๋์ ๋ชจ๋ ์์์ ๋ฐฐ์ด sub-constructor๋ including of()).
class MyArray extends Array { ... } console.log(MyArray.of(3, 11, 8) instanceof MyArray); // true console.log(MyArray.of(3).length === 1); // true
Array.of()๋ ๋ํ ์ ์ฉํ๋ค ํจ์๋งํผ ๊ฐ์ง๊ณ ๊ฐ์ง๊ณ ์์ง ์๋ค ๋ฐฐ์ด์ ๋ณ๋์ ๋ฐฐ์ด์์ ํฌ์ฅ ๊ฐ๊ณผ ๊ด๋ จ์๋ค. ๊ทธ๋ฌ๋, Array.prototype.map()์ ๋ํ ํธ๊ธฐ์ฌ์ ๋น์ ์ ์ฌ๊ธฐ์ ์ค์ ํ ์ ์๋ค.
> ['a', 'b'].map(Array.of) [ [ 'a', 0, [ 'a', 'b' ] ], [ 'b', 1, [ 'a', 'b' ] ] ] > ['a', 'b'].map(x => Array.of(x)) // better [ [ 'a' ], [ 'b' ] ] > ['a', 'b'].map(x => [x]) // best (in this case) [ [ 'a' ], [ 'b' ] ]
๋น์ ์ด ์๋ฅผ ๋ณธ๋ค๋ฉด, map()์ ๊ทธ๊ฒ์ callback์ 3๊ฐ์ง ํ๋ผ๋ฏธํฐ๋ค์ ํต๊ณผ์์ผฐ๋ค, ๋ง์ง๋ง ๋๊ฐ๋ ๋จ์ํ ์ข ์ข ๋ฌด์๋๋ค
2. Prototype methods
๋ช๊ฐ์ ์๋ก์ด ๋ฉ์๋๋ ๋ฐฐ์ด์ ์ธ์คํด์ค๋ค์ด ๊ฐ๋ฅํ๋ค.
2.1 Iterating over arrays
๋ค์ ๋ฉ์๋๋ค์ ๋ฐฐ์ด๋ค์ ๋ฐ๋ณต์์ ๋๋๋ค.
Array.prototype.entries()
Array.prototype.keys()
Array.prototype.values()
์์ ์ธ๊ธํ ๋ฉ์๋์ ๊ฐ ๊ฒฐ๊ณผ๋ ๊ฐ์ ์ฐ์์ด๋ค, ๊ทธ๋ฌ๋ ๊ทธ๋ค์ ๋ฐฐ์ด๋งํผ ๋๋์ ์ค์ง ์๋๋ค; ๊ทธ๋ค์ ํ๋์ ์ํด ํ๋๊ฐ ๋๋ฌ๋๋ค, ์ฐ์ฐ์๋ฅผ ํตํด. ์์ ๋ฅผ ๋ณด์(๋๋ Array.from()์ ์ฌ์ฉ์ค์ด๋ค. (๋ฐฐ์ด์์ ์ฐ์ฐ์์ ์ปจํ ์ธ ๋ฅผ ๋ฃ๊ธฐ์ํด)
> Array.from([ 'a', 'b' ].keys()) [ 0, 1 ] > Array.from([ 'a', 'b' ].values()) [ 'a', 'b' ] > Array.from([ 'a', 'b' ].entries()) [ [ 0, 'a' ],[ 1, 'b' ] ]
๋น์ ์ entries()์ ECMAScrip6์ for-of loop์์ ๊ฒฐํฉ ํ ์ ์๊ณ (index, element) ํ ์์ผ๋ก ํธ๋ฆฌํ ์ฐ์ฐ์ ํํค์น ์ ์๋ค.
for (let [index, elem] of ['a', 'b'].entries()) { console.log(index, elem); }
์ด ์ฝ๋๋ ํ์ฌ ํ์ด์ดํด์ค์๋ ๋ฒ์จ ์ ์ฉ๋๋ค.
2.2 Searching for array elements
Array.prototype.find(predicate, thisArg?)๋ ๋๋์ ์จ๋ค ์ฒซ๋ฒ์งธ ๋ฐฐ์ด ์๋ฆฌ๋จผํธ๊ฐ ์ํ callback predicate์ true ๋๋๋ฆฐ๋ค. ๋ง์ฝ์ ๊ฑฐ๊ธฐ์ ๊ฐ ์๋ฆฌ๋จผํธ๊ฐ ์๋ค๋ฉด ๊ทธ๊ฒ์ undefined๋ฅผ ๋๋๋ฆด ๊ฒ์ด๋ค. ์์ :
> [6, -5, 8].find(x => x < 0) -5 > [6, 5, 8].find(x => x < 0) undefined
Array.prototype.findIndex(predicate, thisArg?)๋ ๋์์จ๋ค ์ฒซ๋ฒ์งธ ์๋ฆฌ๋จผํธ์ ์ธ๋ฑ์ค๊ฐ callback predicate๋ true๋ฅผ ๋ฆฌํดํ๋ค. ๋ง์ฝ ๊ฑฐ๊ธฐ์ ์๋ฆฌ๋จผํธ๊ฐ ์๋ค๋ฉด, ๊ทธ๊ฒ์ -1์ ๋ฆฌํดํ๋ค. ์์ :
> [6, -5, 8].findIndex(x => x < 0) 1 > [6, 5, 8].findIndex(x => x < 0) -1
๋๊ฐ์ find* ๋ฉ์๋๋ holes๋ฅผ ๋ฌด์ํ๋ค. ์ ์ฒด ์ฝ๋ฐฑ predicate์ ์๊ทธ๋์ฒ์ด๋ค.
predicate(element, index, array)
findIndex()๋ฅผ ํตํด NaN์ ์ฐพ๋ ์ค์ด๋ค.
์ ์๋ค Array.prototype.indexOf์ ๋ฆฌ๋ฏธํ ์ด์ ์ NaN์ ์ฐพ์ ์ ์๋ ๊ฒ์ด๋ค. ๋๋ฌธ์ ๊ทธ๊ฒ์ โ===โ๋ฅผ ํตํด ์๋ฆฌ๋จผํธ๋ฅผ ์ํด ์ฐพ๋๋ค.
[NaN].indexOf(NaN) -1
findIndex()์ ๊ฐ์ด, ๋น์ ์ Object.is()[4]๋ฅผ ์ฌ์ฉํ๊ณ ๊ฐ ๋ฌธ์ ๊ฐ ์์ ๊ฒ์ด๋ค.
> [NaN].findIndex(y => Object.is(NaN, y)) 0
๋น์ ์ ๋ํ ์ธ์ ์๋ค ๋ ์ผ๋ฐ์ ์ธ ์ ๊ทผ์ผ๋ก, ํจ์ elemIs()์ ๋์ด์๋ฅผ ๋ง๋ฌ์ ์ํด:
> function elemIs(x) { return Object.is.bind(Object, x) } > [NaN].findIndex(elemIs(NaN)) 0
2.3 Array.prototype.fill(value, start?, end?)
์ฃผ์ด์ง ๊ฐ์ผ๋ก ๋ฐฐ์ด์ ์ฑ์ฐ์๊ณ ์
> ['a', 'b', 'c'].fill(7) [ 7, 7, 7 ]
3๋ฒ์งธ๋ ํน๋ณํ ์น๋ฃ๋ฅผ ๋ฐ์ ์ ์๋ค.
> new Array(3).fill(7) [ 7, 7, 7 ]
์์จ์ ์ผ๋ก, ๋น์ ์ ์ ํ ํ ์ ์๋ค ์์๊ณผ ๋์ ํฌ๋งํ๋ค
> ['a', 'b', 'c'].fill(7, 1, 2) [ 'a', 7, 'c' ]
์ธ์ ํ ์์๋ค ๋๋ ์๋ก์ด ๋ฐฐ์ด์ ์ฌ์ฉํ ์ ์๋์?
๊ทธ๋ค์ ๋ช๊ฐ์ง ๊ฒ๋ค์ ๋ธ๋ผ์ฐ์ ์์ ๋ฒ์จ ๊ฐ๋ฅํ๊ณ . ํํ๊ฒ๋ kangax์ ECMAScript 6 compatibillty tableโ ์ฒดํฌํ์ [es6-shiml] [http://kangax.github.io/compat-table/es6/]
Paul Miller์ es6-shim library ECMAScript5์์ ๊ทธ๊ฒ์ backport ๊ฐ์ง์ ์๋ค.
References
1.Subclassing builtins in ECMAScript 6
2.Iterators and generators in ECMAScript 6
3.โHoles in Arraysโ (Speaking JavaScript)
4.Stricter equality in JavaScript
๋ฒ์ญ์ ๋ธ๋ก๊ทธ
โhttp://www.2ality.com/2014/05/es6-array-methods.htmlโ












