π’ 22/05/31 볡μ΅
javascript.info, https://ko.javascript.info/iterable
μ°Έκ³ μ¬μ΄νΈμ λ΄μ©μ κ°μΈμ μΌλ‘ 볡μ΅νκΈ° νΈνλλ‘ μ¬κ΅¬μ±ν κΈμ λλ€.
μμΈν μ€λͺ μ μ°Έκ³ μ¬μ΄νΈλ₯Ό μ΄ν΄λ³΄μκΈ° λ°λλλ€.
λ°λ³΅ κ°λ₯ν(iterable, μ΄ν°λ¬λΈ) κ°μ²΄λ λ°°μ΄μ μΌλ°νν κ°μ²΄μ
λλ€. μ΄ν°λ¬λΈ μ΄λΌλ κ°λ
μ μ¬μ©νλ©΄ μ΄λ€ κ°μ²΄μλ for..of
λ°λ³΅λ¬Έμ μ μ©ν μ μμ΅λλ€.
λ°°μ΄μ λνμ μΈ μ΄ν°λ¬λΈμ λλ€. λ°°μ΄ μΈμλ λ€μμ λ΄μ₯ κ°μ²΄κ° λ°λ³΅ κ°λ₯ν©λλ€. λ¬Έμμ΄ μμ μ΄ν°λ¬λΈμ μμ λλ€.
λ°°μ΄μ΄ μλ κ°μ²΄κ° μλλ°, μ΄ κ°μ²΄κ° μ΄λ€ κ²λ€μ 컬λ μ
(λͺ©λ‘, μ§ν© λ±)μ λνλ΄κ³ μλ κ²½μ°, for..of
λ¬Έλ²μ μ μ©ν μλ§ μλ€λ©΄ 컬λ μ
μ μννλλ° μ μ©ν κ²λλ€. μ΄κ² κ°λ₯νλλ‘ ν΄λ΄
μλ€.
μ§μ μ΄ν°λ¬λΈ κ°μ²΄λ₯Ό λ§λ€μ΄ μ΄ν°λ¬λΈμ΄λΌλ κ°λ μ μ΄ν΄ν΄ 보λλ‘ ν©μλ€.
for..of
λ₯Ό μ μ©νκΈ°μ μ ν©ν΄ 보μ΄λ λ°°μ΄μ΄ μλ κ°μ²΄λ₯Ό λ§λ€κ² μ΅λλ€.
μμμ κ°μ²΄ range
λ μ«μ κ°κ²©μ λνλ΄κ³ μμ΅λλ€.
let range = {
from: 1,
to: 5
};
// μλμ κ°μ΄ for..ofκ° λμν μ μλλ‘ νλ κ² λͺ©νμ
λλ€.
// for(let num of range) ... num=1,2,3,4,5
range
λ₯Ό μ΄ν°λ¬λΈλ‘ λ§λ€λ €λ©΄(for..of
κ° λμνλλ‘ νλ €λ©΄) κ°μ²΄μ Symbol.iterator
(νΉμ λ΄μ₯ μ¬λ³Ό)λΌλ λ©μλλ₯Ό μΆκ°ν΄ μλμ κ°μ μΌμ΄ λ²μ΄μ§λλ‘ ν΄μΌ ν©λλ€.
for..of
κ° μμλμλ§μ for..of
λ Symbol.iterator
λ₯Ό νΈμΆν©λλ€(Symbol.iterator
κ° μμΌλ©΄ μλ¬κ° λ°μν©λλ€). Symbol.iterator
λ λ°λμ μ΄ν°λ μ΄ν°(iterator
, λ©μλ next
κ° μλ κ°μ²΄) λ₯Ό λ°νν΄μΌ ν©λλ€.
μ΄ν for..of
λ λ°νλ κ°μ²΄(μ΄ν°λ μ΄ν°)λ§μ λμμΌλ‘ λμν©λλ€.
for..of
μ λ€μ κ°μ΄ νμνλ©΄, for..of
λ μ΄ν°λ μ΄ν°μ next()
λ©μλλ₯Ό νΈμΆν©λλ€.
next()
μ λ°ν κ°μ {done: Boolean, value: any}
μ κ°μ ννμ΄μ΄μΌ ν©λλ€. done=true
λ λ°λ³΅μ΄ μ’
λ£λμμμ μλ―Έν©λλ€. done=false
μΌλ value
μ λ€μ κ°μ΄ μ μ₯λ©λλ€.
range
λ₯Ό λ°λ³΅ κ°λ₯ν κ°μ²΄λ‘ λ§λ€μ΄μ£Όλ μ½λλ λ€μκ³Ό κ°μ΅λλ€.
let range = {
from: 1,
to: 5
};
// 1. for..of μ΅μ΄ νΈμΆ μ, Symbol.iteratorκ° νΈμΆλ©λλ€.
range[Symbol.iterator] = function() {
// Symbol.iteratorλ μ΄ν°λ μ΄ν° κ°μ²΄λ₯Ό λ°νν©λλ€.
// 2. μ΄ν for..ofλ λ°νλ μ΄ν°λ μ΄ν° κ°μ²΄λ§μ λμμΌλ‘ λμνλλ°, μ΄λ λ€μ κ°λ μ ν΄μ§λλ€.
return {
current: this.from,
last: this.to,
// 3. for..of λ°λ³΅λ¬Έμ μν΄ λ°λ³΅λ§λ€ next()κ° νΈμΆλ©λλ€.
next() {
// 4. next()λ κ°μ κ°μ²΄ {done:.., value :...}ννλ‘ λ°νν΄μΌ ν©λλ€.
if (this.current <= this.last) {
return { done: false, value: this.current++ };
} else {
return { done: true };
}
}
};
};
// μ΄μ μλν λλ‘ λμν©λλ€!
for (let num of range) {
alert(num); // 1, then 2, 3, 4, 5
}
μ΄ν°λ¬λΈ κ°μ²΄μ ν΅μ¬μ "κ΄μ¬μ¬μ λΆλ¦¬(Separation of concern, SoC)"μ μμ΅λλ€.
range
μ λ©μλ next()
κ° μμ΅λλ€.
λμ range[Symbol.iterator]()
λ₯Ό νΈμΆν΄μ λ§λ "μ΄ν°λ μ΄ν°" κ°μ²΄μ μ΄ κ°μ²΄μ λ©μλ next()
μμ λ°λ³΅μ μ¬μ©λ κ°μ λ§λ€μ΄λ
λλ€.
μ΄λ κ² νλ©΄ μ΄ν°λ μ΄ν° κ°μ²΄μ λ°λ³΅ λμμΈ κ°μ²΄λ₯Ό λΆλ¦¬ν μ μμ΅λλ€.
μ΄ν°λ μ΄ν° κ°μ²΄μ λ°λ³΅ λμ κ°μ²΄λ₯Ό ν©μ³μ range
μ체λ₯Ό μ΄ν°λ μ΄ν°λ‘ λ§λ€λ©΄ μ½λκ° λ κ°λ¨ν΄μ§λλ€.
let range = {
from: 1,
to: 5,
[Symbol.iterator]() {
this.current = this.from;
return this;
},
next() {
if (this.current <= this.to) {
return { done: false, value: this.current++ };
} else {
return { done: true };
}
}
};
for (let num of range) {
alert(num); // 1, then 2, 3, 4, 5
}
μ΄μ range[Symbol.iterator]()
κ° κ°μ²΄ range
μ체λ₯Ό λ°νν©λλ€. λ°νλ κ°μ²΄μ νμ λ©μλμΈ next()
κ° μκ³ this.current
μ λ°λ³΅μ΄ μΌλ§λ μ§νλμλμ§λ₯Ό λνλ΄λ κ°λ μ μ₯λμ΄ μμ΅λλ€. μ½λλ λ 짧μμ‘κ³ μ. μ΄λ κ² μμ±νλ κ² μ’μ λκ° μ’
μ’
μμ΅λλ€.
λ¨μ μ λ κ°μ for..of
λ°λ³΅λ¬Έμ νλμ κ°μ²΄μ λμμ μ¬μ©ν μ μλ€λ μ μ
λλ€. μ΄ν°λ μ΄ν°(κ°μ²΄ μμ )κ° νλλΏμ΄μ΄μ λ λ°λ³΅λ¬Έμ΄ λ°λ³΅ μνλ₯Ό 곡μ νκΈ° λλ¬Έμ΄μ£ . κ·Έλ°λ° λμμ λ κ°μ for..of
λ₯Ό μ¬μ©νλ κ²μ λΉλκΈ° μ²λ¦¬μμλ νν μΌμ΄μ€λ μλλλ€.
π₯ 무νκ°μ μ΄ν°λ μ΄ν°
무μν λ§μ μ΄ν°λ μ΄ν°λ κ°λ₯ν©λλ€. range
μμ range.to
μ Infinity
λ₯Ό ν λΉνλ©΄ range
κ° λ¬΄νλκ° λμ£ . 무μν λ§μ μμ¬ λμ(pseudorandom numbers)λ₯Ό μμ±νλ μ΄ν°λ¬λΈ κ°μ²΄λ₯Ό λ§λλ κ²λ κ°λ₯ν©λλ€. μ΄ λ°©λ²μ΄ μ μ©νκ² μ°μ΄λ κ²½μ°λ μμ΅λλ€.
next
μ μ μ½μ¬νμ΄ μμ΅λλ€. next
κ° κ°μ κ³μ λ°ννλ κ²μ μ μμ μΈ λμμ
λλ€.
λ¬Όλ‘ μμ κ°μ μ΄ν°λ¬λΈμ for..of
λ°λ³΅λ¬Έμ μ¬μ©νλ©΄ λμ΄ μμ κ²λλ€. κ·Έλ λ€ νλλΌλ break
λ₯Ό μ¬μ©νλ©΄ μΈμ λ μ§ λ°λ³΅μ λ©μΆ μ μμ΅λλ€.
λ°°μ΄κ³Ό λ¬Έμμ΄μ κ°μ₯ κ΄λ²μνκ² μ°μ΄λ λ΄μ₯ μ΄ν°λ¬λΈμ λλ€.
for..of
λ λ¬Έμμ΄μ κ° κΈμλ₯Ό μνν©λλ€.
for (let char of "test") {
// κΈμ νλλΉ ν λ² μ€νλ©λλ€(4ν νΈμΆ).
alert( char ); // t, e, s, tκ° μ°¨λ‘λλ‘ μΆλ ₯λ¨
}
μλ‘κ²μ΄νΈ μ(surrogate pair)μλ μ λμν©λλ€.
let str = "π³π";
for (let char of str) {
alert( char ); // π³μ πκ° μ°¨λ‘λλ‘ μΆλ ₯λ¨
}
μ΄ν°λ μ΄ν°λ₯Ό μ΄λ»κ² λͺ μμ μΌλ‘ μ¬μ©ν μ μλμ§ μ΄ν΄λ³΄λ©΄μ μ’ λ κΉκ² μ΄ν΄ν΄λ΄ μλ€.
for..of
λ₯Ό μ¬μ©νμ λμ λμΌν λ°©λ²μΌλ‘ λ¬Έμμ΄μ μνν 건λ°, μ΄λ²μ μ§μ νΈμΆμ ν΅ν΄μ μνν΄λ³΄κ² μ΅λλ€. λ€μ μ½λλ λ¬Έμμ΄ μ΄ν°λ μ΄ν°λ₯Ό λ§λ€κ³ , μ¬κΈ°μ κ°μ "μλμΌλ‘" κ°μ Έμ΅λλ€.
let str = "Hello";
// for..ofλ₯Ό μ¬μ©ν κ²κ³Ό λμΌν μμ
μ ν©λλ€.
// for (let char of str) alert(char);
let iterator = str[Symbol.iterator]();
while (true) {
let result = iterator.next();
if (result.done) break;
alert(result.value); // κΈμκ° νλμ© μΆλ ₯λ©λλ€.
}
μ΄ν°λ μ΄ν°λ₯Ό λͺ
μμ μΌλ‘ νΈμΆνλ κ²½μ°λ κ±°μ μλλ°, μ΄ λ°©λ²μ μ¬μ©νλ©΄ for..of
λ₯Ό μ¬μ©νλ κ²λ³΄λ€ λ°λ³΅ κ³Όμ μ λ μ ν΅μ ν μ μλ€λ μ₯μ μ΄ μμ΅λλ€. λ°λ³΅μ μμνλ€κ° μ μ λ©μΆ° λ€λ₯Έ μμ
μ νλ€κ° λ€μ λ°λ³΅μ μμνλ κ²κ³Ό κ°μ΄ λ°λ³΅ κ³Όμ μ μ¬λ¬ κ°λ‘ μͺΌκ°λ κ²μ΄ κ°λ₯ν©λλ€.
λΉμ·ν΄ 보μ΄μ§λ§ μμ£Ό λ€λ₯Έ μ©μ΄ λ κ°μ§κ° μμ΅λλ€. ν·κ°λ¦¬μ§ μμΌλ €λ©΄ λ μ©μ΄λ₯Ό μ μ΄ν΄νκ³ μμ΄μΌ ν©λλ€.
μ΄ν°λ¬λΈ(iterable) μ μμμ μ€λͺ
ν λ°μ κ°μ΄ λ©μλ Symbol.iterator
κ° κ΅¬νλ κ°μ²΄μ
λλ€.
μ μ¬ λ°°μ΄(array-like) μ μΈλ±μ€μ length
νλ‘νΌν°κ° μμ΄μ λ°°μ΄μ²λΌ 보μ΄λ κ°μ²΄μ
λλ€.
λΈλΌμ°μ λ λ±μ νΈμ€νΈ νκ²½μμ μλ°μ€ν¬λ¦½νΈλ₯Ό μ¬μ©ν΄ λ¬Έμ λ₯Ό ν΄κ²°ν λ μ΄ν°λ¬λΈ κ°μ²΄λ μ μ¬ λ°°μ΄ κ°μ²΄ νΉμ λ λ€μΈ κ°μ²΄λ₯Ό λ§λ μ μμ΅λλ€.
μ΄ν°λ¬λΈ κ°μ²΄(for..of λ₯Ό μ¬μ©ν μ μμ)μ΄λ©΄μ μ μ¬λ°°μ΄ κ°μ²΄(μ«μ μΈλ±μ€μ length νλ‘νΌν°κ° μμ)μΈ λ¬Έμμ΄μ΄ λνμ μΈ μμ λλ€.
μ΄ν°λ¬λΈ κ°μ²΄λΌκ³ ν΄μ μ μ¬ λ°°μ΄ κ°μ²΄λ μλλλ€. μ μ¬ λ°°μ΄ κ°μ²΄λΌκ³ ν΄μ μ΄ν°λ¬λΈ κ°μ²΄μΈ κ²λ μλλλ€.
μ μμμ range
λ μ΄ν°λ¬λΈ κ°μ²΄μ΄κΈ΄ νμ§λ§ μΈλ±μ€λ μκ³ length
νλ‘νΌν°λ μμΌλ―λ‘ μ μ¬ λ°°μ΄ κ°μ²΄κ° μλλλ€.
μλ μμμ κ°μ²΄λ μ μ¬ λ°°μ΄ κ°μ²΄μ΄κΈ΄ νμ§λ§ μ΄ν°λ¬λΈ κ°μ²΄κ° μλλλ€.
let arrayLike = { // μΈλ±μ€μ lengthνλ‘νΌν°κ° μμ => μ μ¬ λ°°μ΄
0: "Hello",
1: "World",
length: 2
};
// Symbol.iteratorκ° μμΌλ―λ‘ μλ¬ λ°μ
for (let item of arrayLike) {}
μ΄ν°λ¬λΈκ³Ό μ μ¬ λ°°μ΄μ λκ° λ°°μ΄μ΄ μλκΈ° λλ¬Έμ push
, pop
λ±μ λ©μλλ₯Ό μ§μνμ§ μμ΅λλ€. μ΄ν°λ¬λΈκ³Ό μ μ¬ λ°°μ΄μ λ°°μ΄μ²λΌ λ€λ£¨κ³ μΆμ λ μ΄λ° νΉμ§μ λΆνΈν¨μ μ΄λν©λλ€. range
μ λ°°μ΄ λ©μλλ₯Ό μ¬μ©ν΄ 무μΈκ°λ₯Ό νκ³ μΆμ λμ²λΌ λ§μ΄μ£ . μ΄λ»κ² νλ©΄ μ΄ν°λ¬λΈκ³Ό μ μ¬ λ°°μ΄μ λ°°μ΄ λ©μλλ₯Ό μ μ©ν μ μμκΉμ?
λ²μ© λ©μλ Array.from
λ μ΄ν°λ¬λΈμ΄λ μ μ¬ λ°°μ΄μ λ°μ "μ§μ§" Array
λ₯Ό λ§λ€μ΄μ€λλ€. μ΄ κ³Όμ μ κ±°μΉλ©΄ μ΄ν°λ¬λΈμ΄λ μ μ¬ λ°°μ΄μ λ°°μ΄ λ©μλλ₯Ό μ¬μ©ν μ μμ΅λλ€.
let arrayLike = {
0: "Hello",
1: "World",
length: 2,
};
let arr = Array.from(arrayLike); // (*)
alert(arr.pop()); // World (λ©μλκ° μ λλ‘ λμν©λλ€.)
(*)
λ‘ νμν μ€μ μλ Array.from
μ κ°μ²΄λ₯Ό λ°μ μ΄ν°λ¬λΈμ΄λ μ μ¬ λ°°μ΄μΈμ§ μ‘°μ¬ν©λλ€. λ겨 λ°μ μΈμκ° μ΄ν°λ¬λΈμ΄λ μ μ¬ λ°°μ΄μΈ κ²½μ°, μλ‘μ΄ λ°°μ΄μ λ§λ€κ³ κ°μ²΄μ λͺ¨λ μμλ₯Ό μλ‘κ² λ§λ λ°°μ΄λ‘ 볡μ¬ν©λλ€.
// rangeλ μ±ν° μμͺ½ μμμμ κ·Έλλ‘ κ°μ Έμλ€κ³ κ°μ ν©μλ€.
let arr = Array.from(range);
alert(arr); // 1,2,3,4,5 (λ°°μ΄-λ¬Έμμ΄ ν λ³νμ΄ μ λλ‘ λμν©λλ€.)
Array.from
μ "맀ν(mapping)" ν¨μλ₯Ό μ νμ μΌλ‘ λκ²¨μ€ μ μμ΅λλ€.
Array.from(obj[, mapFn, thisArg])
mapFn
μ λ λ²μ§Έ μΈμλ‘ λ겨주면 μλ‘μ΄ λ°°μ΄μ obj
μ μμλ₯Ό μΆκ°νκΈ° μ μ κ° μμλ₯Ό λμμΌλ‘ mapFn
μ μ μ©ν μ μμ΅λλ€. μλ‘μ΄ λ°°μ΄μ mapFn
μ μ μ©νκ³ λ°νλ κ°μ΄ μΆκ°λ©λλ€. μΈ λ²μ§Έ μΈμ thisArg
λ κ° μμμ this
λ₯Ό μ§μ ν μ μλλ‘ ν΄μ€λλ€.
// rangeλ μ±ν° μμͺ½ μμμμ κ·Έλλ‘ κ°μ Έμλ€κ³ κ°μ ν©μλ€.
// κ° μ«μλ₯Ό μ κ³±
let arr = Array.from(range, num => num * num);
alert(arr); // 1,4,9,16,25
μλ μμμμ Array.from
λ₯Ό μ¬μ©ν΄ λ¬Έμμ΄μ λ°°μ΄λ‘ λ§λ€μ΄λ³΄μμ΅λλ€.
let str = "π³π";
// strλ₯Ό λΆν΄ν΄ κΈμκ° λ΄κΈ΄ λ°°μ΄λ‘ λ§λ¦
let chars = Array.from(str);
alert(chars[0]); // π³
alert(chars[1]); // π
alert(chars.length); // 2
Array.from
μ str.split
κ³Ό λ¬λ¦¬, λ¬Έμμ΄ μμ²΄κ° κ°μ§ μ΄ν°λ¬λΈ μμ±μ μ΄μ©ν΄ λμν©λλ€. λ°λΌμ for..of
μ²λΌ μλ‘κ²μ΄νΈ μμλ μ λλ‘ μ μ©λ©λλ€.
μ μμλ κΈ°μ μ μΌλ‘ μλ μμμ λμΌνκ² λμνλ€κ³ 보μλ©΄ λ©λλ€.
let str = "π³π";
let chars = []; // Array.from λ΄λΆμμ μλμ λμΌν λ°λ³΅λ¬Έμ΄ λμκ°λλ€.
for (let char of str) {
chars.push(char);
}
alert(chars);
μ΄μ¨λ Array.from
μ μ¬μ©ν μμκ° λ 짧μ΅λλ€.
Array.from
μ μ¬μ©νλ©΄ μλ‘κ²μ΄νΈ μμ μ²λ¦¬ν μ μλ slice
λ₯Ό μ§μ ꡬνν μλ μμ΅λλ€.
function slice(str, start, end) {
return Array.from(str).slice(start, end).join("");
}
let str = "π³ππ©·Ά";
alert( slice(str, 1, 3) ); // ππ©·Ά
// λ΄μ₯ μμ λ©μλλ μλ‘κ²μ΄νΈ μμ μ§μνμ§ μμ΅λλ€.
alert( str.slice(1, 3) ); // μ°λ κΉκ° μΆλ ₯ (μμμ΄ λ€λ₯Έ νΉμ κ°)