8. ํ•จ์ˆ˜ (8.8~11)

Woogieยท2022๋…„ 10์›” 18์ผ
0
post-thumbnail

8.8 ๊ฐ์ฒด๋กœ์„œ์˜ ํ•จ์ˆ˜๐Ÿ‘Š


8.8.1 ํ•จ์ˆ˜๋Š” ๊ฐ์ฒด

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ•จ์ˆ˜๋Š” Function ๊ฐ์ฒด๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํŠน์ง•์ด ์žˆ๋‹ค.

  • ํ•จ์ˆ˜๋Š” ๋ณ€์ˆ˜๋‚˜ ํ”„๋กœํผํ‹ฐ๋‚˜ ๋ฐฐ์—ด ์š”์†Œ์— ๋Œ€์ž…ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ํ•จ์ˆ˜๋Š” ํ•จ์ˆ˜์˜ ์ธ์ˆ˜๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ํ•จ์ˆ˜๋Š” ํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜๊ฐ’์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ํ•จ์ˆ˜๋Š” ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค.
  • ํ•จ์ˆ˜๋Š” ์ด๋ฆ„ ์—†๋Š” ๋ฆฌํ„ฐ๋Ÿด๋กœ ํ‘œํ˜„ ๊ฐ€๋Šฅํ•˜๋‹ค. (์ต๋ช…ํ•จ์ˆ˜)
  • ํ•จ์ˆ˜๋Š” ๋™์ ์œผ๋กœ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด๋Ÿฌํ•œ ์ž‘์—…์ด ๊ฐ€๋Šฅํ•œ ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌ์ผœ ์ผ๊ธ‰ ๊ฐ์ฒด ๋ผ๊ณ  ํ•˜๋ฉฐ ์ผ๊ธ‰ ๊ฐ์ฒด์ธ ํ•จ์ˆ˜๋Š” ์ผ๊ธ‰ ํ•จ์ˆ˜ ๋ผ๊ณ  ํ•œ๋‹ค.

8.8.2 ํ•จ์ˆ˜์˜ ํ”„๋กœํผํ‹ฐ

ํ•จ์ˆ˜์˜ ํ”„๋กœํผํ‹ฐ

  • caller : ํ˜„์žฌ ์‹คํ–‰ ์ค‘์ธ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ ํ•จ์ˆ˜
  • length : ํ•จ์ˆ˜์˜ ์ธ์ž ๊ฐœ์ˆ˜
  • name : ํ•จ์ˆ˜๋ฅผ ํ‘œ์‹œํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ์ด๋ฆ„
  • prototype : ํ”„๋กœํ† ํƒ€์ž… ๊ฐ์ฒด์˜ ์ฐธ์กฐ

Function.prototype์˜ ํ”„๋กœํผํ‹ฐ

  • apply() : ์„ ํƒํ•œ this์™€ ์ธ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœ. ์ธ์ˆ˜๋Š” ๋ฐฐ์—ด ๊ฐ์ฒด
  • bind() : ์„ ํƒํ•œ this์™€ ์ธ์ˆ˜๋ฅผ ์ ์šฉํ•œ ์ƒˆ๋กœ์šด ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜
  • call() : ์„ ํƒํ•œ this์™€ ์ธ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœ. ์ธ์ˆ˜๋Š” ์‰ผํ‘œ๋กœ ๊ตฌ๋ถ„
  • constructor : Function ์ƒ์„ฑ์ž์˜ ์ฐธ์กฐ
  • toString() : ํ•จ์ˆ˜์˜ ์†Œ์Šค ์ฝ”๋“œ๋ฅผ ๋ฌธ์ž์—ด๋กœ ๋งŒ๋“ค์–ด ๋ฐ˜ํ™˜

8.8.3 apply์™€ call ๋ฉ”์„œ๋“œ

apply() ์™€ call() ๋™์ž‘์€ this๊ฐ’๊ณผ ํ•จ์ˆ˜์˜ ์ธ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•œ๋‹ค๋Š” ๊ณตํ†ต์ ์ด ์žˆ๋‹ค.
์ฐจ์ด์ ์€ apply()์˜ ์ธ์ˆ˜๋Š” ๋ฐฐ์—ด์ด๊ณ , call()์˜ ์ธ์ˆ˜๋Š” ์‰ผํ‘œ๋กœ ๊ตฌ๋ถ„ํ•œ๋‹ค.

function say(greetings, honorifics) {
  console.log(`${greetings} "${honorifics} ${this.name}`);
}

var tom = { name: "Tom Sawyer" };
var becky = { name: "Becky Thatcher" };

say.apply(tom, ["Hello!", "Mr."]); // Hello! "Mr. Tom Sawyer
say.call(becky, "Hi!", "Ms."); // Hi! "Ms. Becky Thatcher

8.9 ๊ณ ์ฐจ ํ•จ์ˆ˜๐Ÿ‘Š


8.9.1 ๊ณ ์ฐจ ํ•จ์ˆ˜

ํ•จ์ˆ˜๋ฅผ ์ธ์ˆ˜๋กœ ๋ฐ›๋Š” ํ•จ์ˆ˜ ๋˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋งํ•œ๋‹ค. ๊ณ ์ฐจ ํ•จ์ˆ˜๋Š” ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ํ•  ๋•Œ ์ž์ฃผ ์‚ฌ์šฉํ•œ๋‹ค. ๊ทธ ์˜ˆ๋กœ๋Š” map, filter, reduce ๋“ฑ์ด ์žˆ๋‹ค.

ํŒจํ„ด์ด ๊ฐ™์€ ์ž‘์—…์„ ๊ณ ์ฐจ ํ•จ์ˆ˜๋กœ ์ •๋ฆฌํ•˜๋Š” ์˜ˆ

digits = "";
for (var i = 0; i < 10; i++) {
  digits += i;
}
console.log(digits); // 0123456789;
randomChars = "";
for (var i = 0; i < 8; i++) {
  randomChars += String.fromCharCode(
    Math.floor(Math.random() * 26) + "a".charCodeAt(0)
  );
}
console.log(randomChars); // ๋ฌด์ž‘์œ„ ์•ŒํŒŒ๋ฒณ ๋ฌธ์ž์—ด

์œ„์˜ ๋‘ ์ฝ”๋“œ๋Š” ํ•˜๋Š” ์ผ์ด ๋‹ค๋ฅด์ง€๋งŒ ๋กœ์ง์€ ๊ฐ™๋‹ค. ๊ณตํ†ต ๋ถ€๋ถ„์„ ๊ณ ์ฐจ ํ•จ์ˆ˜๋กœ ๋งŒ๋“ค์–ด๋ณด์ž

function joinString(n, f) {
  var s = "";
  for (var i = 0; i < n; i++) {
    s += f(i);
  }
  return s;
}
var digits = joinString(10, function (i) {
  return i;
});
var randomChars = joinString(8, function (i) {
  return String.fromCharCode(
    Math.floor(Math.random() * 26) + "a".charCodeAt(0)
  );
});
console.log(digits);		//0123456789
console.log(randomChars);	// ๋ฌด์ž‘์œ„ ์•ŒํŒŒ๋ฒณ ๋ฌธ์ž์—ด

8.9.2 ๋ฉ”๋ชจ์ด์ œ์ด์…˜

ํ•จ์ˆ˜์— ํ”„๋กœํผํ‹ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ๊ฒฐ๊ณผ(๋ฐ˜ํ™˜ ๊ฐ’)๋ฅผ ์บ์‹ฑํ•˜์—ฌ ๋‹ค์Œ ํ˜ธ์ถœ ์‹œ์ ์— ๋ณต์žกํ•œ ์—ฐ์‚ฐ์„ ๋ฐ˜๋ณตํ•˜์ง€ ์•Š๊ฒŒ ํ•˜๋Š” ํŒจํ„ด์„ Memoization(๋ฉ”์ด๋ชจ์ œ์ด์…˜) ํŒจํ„ด์ด๋ผ๊ณ  ํ•œ๋‹ค.

function memorize(f) {
  var cache = {};
  return function (x) {
    if (cache[x] == undefined) cache[x] = f(x);
    return cache[x];
  };
}

memorize ํ•จ์ˆ˜๋Š” ์ธ์ˆ˜๋กœ ๋ฐ›์€ ํ•จ์ˆ˜์˜ ์‹คํ–‰ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ์ฒด cache ์•ˆ์— ์ €์žฅํ•œ๋‹ค. ์ด ๋•๋ถ„์— ์ธ์ˆ˜๋กœ ๋ฐ›์€ ํ•จ์ˆ˜๋ฅผ ๊ฐ™์€ ์ธ์ˆ˜๋กœ ์‹คํ–‰ํ•˜๋ฉด ์‹ค์ œ ๊ณ„์‚ฐ์„ ํ•˜๋Š” ๋Œ€์‹  cache์— ์ €์žฅ๋œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๊ฐ€ ๋งŒ๋“ค์–ด์ง„๋‹ค

memorize ํ•จ์ˆ˜์˜ ์‚ฌ์šฉ ์˜ˆ

// ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ํ”ผ๋ณด๋‚˜์น˜์ˆ˜์—ด
function memorize(f) {
  var cache = {};
  return function (x) {
    if (cache[x] == undefined) cache[x] = f(x);
    return cache[x];
  };
}
var fibonacci = memorize(function (n) {
  if (n < 2) return n;
  return fibonacci(n - 1) + fibonacci(n - 2);
});
for (var i = 0; i <= 20; i++) {
  console.log((" " + i).slice(-2) + ":" + fibonacci(i));
}

8.9.3 ํ•จ์ˆ˜์˜ ํ•ฉ์„ฑ

ํ•จ์ˆ˜ f(x)์™€ g(x)๊ฐ€ ์žˆ์„ ๋•Œ ํ•จ์ˆ˜ f(g(x))์˜ ํ•ฉ์„ฑ ํ•จ์ˆ˜๋ผ๊ณ  ํ•œ๋‹ค.

function compose(f,g) {
    return funciton(x) {
        return f(g(x));
    };
}

var square = function(x) {
    return x*x;
}
var add1 = function(x) {
    return x+1;
}
var h = compose(square,add1);
console.log(h2));

์ธ์ˆ˜ ์—ฌ๋Ÿฌ๊ฐœ๋„ ๊ฐ€๋Šฅ

function compose(f, g) {
  return function () {
    return f.call(this, g.apply(this, arguments));
  };
}

8.9.4 ๋ถ€๋ถ„ ์ ์šฉ

์ธ์ˆ˜๋ฅผ ์—ฌ๋Ÿฌ ๊ฐœ ๋ฐ›๋Š” ํ•จ์ˆ˜์˜ ๋ช‡๋ช‡ ์ธ์ˆ˜๋ฅผ ์ƒ์ˆ˜๋กœ ์ง€์ •ํ•ด์„œ ์ƒˆ๋กœ์šด ํ•จ์ˆ˜๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ธฐ๋ฒ•

function product(x, y) {
  return x * y;
}
product2 = function (y) {
  return product(2, y);
};
product(3); // 6

// bind ์‚ฌ์šฉ
product2 = product.bind(null, 2);
// ๋ถ€๋ถ„ ์ ์šฉ๋œ ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜
function partial(f) {
  // ์ค‘์ฒฉ ํ•จ์ˆ˜์—์„œ arguments๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์ €์žฅํ•ด ๋‘ 
  var args = arguments;
  return function () {
    // ์™ธ๋ถ€ ํ•จ์ˆ˜์˜ ๋‘ ๋ฒˆ์งธ ์ธ์ˆ˜๋ฅผ ๋ณ€์ˆ˜ a์— ๋ณต์‚ฌ
    var a = Array.prototype.slice.call(args, 1);
    for (var i = 0, j = 0; i < a.length; i++) {
      // ์™ธ๋ถ€ ํ•จ์ˆ˜์˜ ๋‘ ๋ฒˆ์งธ ์ธ์ˆ˜๊ฐ€ undefined๋ฉด ์ด ํ•จ์ˆ˜์˜ arguments๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
      if (a[i] == undefined) a[i] = arguments[j++];
    }
    return f.apply(this, a);
  };
}
var square = partial(Math.pow, undefined, 2);
var sqrt = partial(Math.pow, undefined, 0.5);
var cubicroot = partial(Math.pow, undefined, 1 / 3);
var exp = partial(Math.pow, Math.E, undefined);

// *arguments๋Š” ๋ฐฐ์—ด์ด ์•„๋‹Œ ์œ ์‚ฌ ๋ฐฐ์—ด ๊ฐ์ฒด์ด๊ธฐ ๋•Œ๋ฌธ์— Array.prototype.slice์˜
// call ๋ฉ”์„œ๋“œ์— args๋ฅผ ์ธ์ˆ˜๋กœ ๋„˜๊ฒจ์„œ ํ˜ธ์ถœ

8.9.5 ์ปค๋ง

์ธ์ˆ˜๋ฅผ ๋‘ ๊ฐœ ์ด์ƒ ๋ฐ›๋Š” ํ•จ์ˆ˜๋ฅผ ๋ถ„ํ•ดํ•˜์—ฌ ์ธ์ˆ˜๊ฐ€ ํ•˜๋‚˜์ธ ํ•จ์ˆ˜์˜ ์ค‘์ฒฉ ํ•จ์ˆ˜๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ์ž‘์—…

var pow = function (exponent) {
  return function (base) {
    return Math.pow(base, exponent);
  };
};
// ์ด๋ ‡๊ฒŒ ์ •์˜ํ•œ ํ•จ์ˆ˜ pow๋Š” Math.pow๋ฅผ ์ปค๋งํ•œ ๊ฒƒ์ž„

Math.pow(base, exponent) = pow(exponent)(base);

8.10 ์ฝœ๋ฐฑํ•จ์ˆ˜๐Ÿ‘Š


8.10.1 ์ฝœ๋ฐฑํ•จ์ˆ˜

๋‹ค๋ฅธ ํ•จ์ˆ˜์— ์ธ์ˆ˜๋กœ ๋„˜๊ฒจ์ง€๋Š” ํ•จ์ˆ˜๋ฅผ ๊ฐ€๋ฆฌ์ผœ ์ฝœ๋ฐฑ ํ•จ์ˆ˜ ๋ผ๊ณ  ํ•œ๋‹ค.
15์žฅ์—์„œ ๋ฐฐ์šธ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ๊ธฐ addEventListener๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ์“ด๋‹ค.

f(g, ...) {
    ...
    function f(callback, ...) {
        ...
        callback();
        ...
    }
}

8.11 ES6๋ถ€ํ„ฐ ์ถ”๊ฐ€๋œ ํ•จ์ˆ˜์˜ ๊ธฐ๋Šฅ๐Ÿ‘Š


8.11.1 ํ™”์‚ดํ‘œ ํ•จ์ˆ˜ ํ‘œํ˜„์‹์œผ๋กœ ํ•จ์ˆ˜ ์ •์˜ํ•˜๊ธฐ

  • var square = (x) => {return x*x; };

    ๊ธฐ์กด์˜ ํ•จ์ˆ˜ ๋ฆฌํ„ฐ๋Ÿด ์ •์˜๋ฅผ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜ ํ‘œํ˜„์‹์œผ๋กœ
  • var f = (x,y,z) => {...};

    ์ธ์ˆ˜๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ ์žˆ์œผ๋ฉด ์ธ์ˆ˜์™€ ์ธ์ˆ˜๋ฅผ ์‰ผํ‘œ๋กœ ๊ตฌ๋ถ„
  • var square = x => {return x*x;};
    ์ธ์ˆ˜๊ฐ€ ํ•˜๋‚˜๋งŒ ์žˆ์œผ๋ฉด ์ธ์ˆ˜ ๋ฌถ๋Š” ๊ด„ํ˜ธ ์ƒ๋žต
  • var f = () => {...};
    ์ธ์ˆ˜๊ฐ€ ์—†์œผ๋ฉด ์ธ์ˆ˜๋ฅผ ๋ฌถ๋Š” ๊ด„ํ˜ธ๋ฅผ ์ƒ๊ฐํ•  ์ˆ˜ ์—†๋‹ค.
  • var square = x => x*x;
    ๋ฌธ์žฅ์ด return ๋ฟ์ด๋ฉด ์ค‘๊ด„ํ˜ธ์™€ return ํ‚ค์›Œ๋“œ๋ฅผ ์ƒ๊ฐ๊ฐ€๋Šฅ
  • ํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜๊ฐ’์ด ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด์ด๋ฉด ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด์„ ๊ทธ๋ฃน ์—ฐ์‚ฐ์ž์ธ ()๋กœ ๋ฌถ์„ ๊ฒƒ
    var f = (a,b) => ({x:a, y:b})

ํ•จ์ˆ˜ ๋ฆฌํ„ฐ๋Ÿด๊ณผ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜์˜ ์ฐจ์ด์ ์„ ์•Œ์•„๋ณด์ž

1. this์˜ ๊ฐ’์ด ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•  ๋•Œ ๊ฒฐ์ •๋œ๋‹ค.

var obj = {
  say: function () {
    console.log(this); // [object Object]
    var f = function () {
      console.log(this);
    }; // [object Window]
    f();
    var g = () => console.log(this); // [object Object]
    g();
  },
};
obj.say();

ํ•จ์ˆ˜ f๋Š” say๋ผ๋Š” ํ•จ์ˆ˜์˜ ์ค‘์ฒฉ ํ•จ์ˆ˜์ด๋ฉฐ this์˜ ๊ฐ’์€ ์ „์—ญ ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค. ํ•œํŽธ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜
g์˜ this๊ฐ’์€ ํ•จ์ˆ˜ g๋ฅผ ์ •์˜ํ•œ ์ต๋ช… ํ•จ์ˆ˜์˜ this์˜ ๊ฐ’์ธ ๊ฐ์ฒด obj๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.
ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” call์ด๋‚˜ apply ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ this๋ฅผ ๋ฐ”๊พธ์–ด ํ˜ธ์ถœํ•ด๋„ this ๊ฐ’์ด ๋ฐ”๋€Œ์ง€ ์•Š๋Š”๋‹ค.

2. arguments ๋ณ€์ˆ˜๊ฐ€ ์—†๋‹ค.

var f = () => console.log(arguments);
f(); // ReferenceError : arguments is not defined

3. ์ƒ์„ฑ์ž๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.

var Person = (name, age) => {
  this.name = name;
  this.age = age;
};
var tom = new Person("Tom", 17); // TypeError : Person is not a contructor

4. yield ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.
ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” ์ œ๋„ˆ๋ ˆ์ดํ„ฐ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค. (324p ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ์ฐธ๊ณ )

8.11.2 ์ธ์ˆ˜์— ์ถ”๊ฐ€๋œ ๊ธฐ๋Šฅ

๋‚˜๋จธ์ง€ ๋งค๊ฐœ๋ณ€์ˆ˜

ํ•จ์ˆ˜์˜ ์ธ์ž๊ฐ€ ๋“ค์–ด๊ฐ€๋Š” ๋ถ€๋ถ„์— ...์„ ์ž…๋ ฅํ•˜๋ฉด ๊ทธ๋งŒํผ์˜ ์ธ์ˆ˜๋ฅผ ๋ฐฐ์—ด๋กœ ๋ฐ›๋Š”๋‹ค.

function args(a, b, ...args) {
  console.log(a, b, args);
}
f(1, 2, 3, 4, 5, 6); // 1 2 [3,4,5,6]

์ธ์ˆ˜์˜ ๊ธฐ๋ณธ๊ฐ’

ํ•จ์ˆ˜์˜ ์ธ์ž์— ๋Œ€์ž…(=) ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ธฐ๋ณธ๊ฐ’์„ ์„ค์ •ํ• ์ˆ˜ ์žˆ๋‹ค.

function multiply(a, b = 1) {
  return a * b;
}
multiply(3); // 3
multiply(3, 2); // 6

8.11.3 ์ดํ„ฐ๋ ˆ์ดํ„ฐ์™€ for/of ๋ฌธ

์ดํ„ฐ๋ ˆ์ด์…˜

์ดํ„ฐ๋ ˆ์ด์…˜์€ ๋ฐ˜๋ณต ์ฒ˜๋ฆฌ ๋ผ๋Š” ๋œป์œผ๋กœ ๋ฐ์ดํ„ฐ ์•ˆ์˜ ์š”์†Œ๋ฅผ ์—ฐ์†์ ์œผ๋กœ ๊บผ๋‚ด๋Š” ํ–‰์œ„

var a = [5, 4, 3];
a.forEach(function (val) {
  console.log(val);
});
// 5
// 4
// 3

์ดํ„ฐ๋ ˆ์ดํ„ฐ

๋ฐฐ์—ด์€ Symbol.iterator ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ณ  ๊ทธ ๋ฉ”์„œ๋“œ๋Š” ์ดํ„ฐ๋ ˆ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค.

var a = [5, 4, 3];
var iter = a[Symbol.iterator]();
console.log(iter.next()); // {value: 5, done: false}
console.log(iter.next()); // {value: 4, done: false}
console.log(iter.next()); // {value: 3, done: false}
console.log(iter.next()); // {value: 2, done: true}
console.log(iter.next()); // {value: 1, done: true}

์ด์ฒ˜๋Ÿผ iter์˜ next ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ๋งˆ๋‹ค ์ดํ„ฐ๋ ˆ์ดํ„ฐ ๋ฆฌ์ ˆํŠธ(iterator result)๋ผ๋Š” ๊ฐ์ฒด๊ฐ€ ๋ฐ˜ํ™˜๋˜๊ณ  ์ดํ„ฐ๋ ˆ์ดํ„ฐ ๋ฆฌ์ ˆํŠธ(iterator result)๋Š” value์™€ done ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ–๋Š”๋‹ค. next๊ฐ€ ํ˜ธ์ถœ ๋  ๋•Œ๋งˆ๋‹ค value ํ”„๋กœํผํ‹ฐ์—๋Š” ์ฐจ๋ก€๋Œ€๋กœ ๊บผ๋‚ด์ง„ ๋ฐฐ์—ด ์š”์†Œ์˜ ๊ฐ’์ด ์ €์žฅ๋˜๊ณ  done ํ”„๋กœํผํ‹ฐ์—๋Š” ์š”์†Œ์˜ ์—ด๊ฑฐ๊ฐ€ ๋๋‚ฌ๋Š”์ง€๋ฅผ ๋œปํ•˜๋Š” ๋…ผ๋ฆฌ๊ฐ’์ด ์ €์žฅ๋œ๋‹ค.

๋ฐ˜๋ณต ๊ฐ€๋Šฅํ•œ ๊ฐ์ฒด์™€ for/of ๋ฌธ

var a = [5, 4, 3];
var iter = a[Symbol.iterator]();
while (true) {
  var iteratorResult = iter.next();
  if (iteratorResult.done == true) break;
  var v = iteratorResult.value;
  console.log(v);
}
// 5
// 4
// 3

for/of ๋ฌธ์„ ์‚ฌ์šฉํ•˜๋ฉด ์ด๋Ÿฌํ•œ ๋ฐ˜๋ณต ์ฒ˜๋ฆฌ๋ฅผ ์ž๋™์œผ๋กœ ํ•˜๋„๋ก ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

var a = [5, 4, 3];
for (var v of a) console.log(v);

for/of ๋ฌธ์€ a ์ดํ„ฐ๋ ˆ์ดํ„ฐ์˜ next ๋ฉ”์„œ๋“œ๋ฅผ ์ˆœํšŒํ•  ๋•Œ๋งˆ๋‹ค ๋งค๋ฒˆ ํ˜ธ์ถœํ•œ๋‹ค.

์ผ๋ฐ˜์ ์œผ๋กœ for/of ๋ฌธ์€ ๋‹ค์Œ ๋‘ ๊ฐ€์ง€ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” ๊ฐ์ฒด๋ฅผ ๋ฐ˜๋ณต ์ฒ˜๋ฆฌ ํ•œ๋‹ค.

  • Symbol.iterator ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.
  • Symbol.iterator ๋ฉ”์„œ๋“œ๋Š” ๋ฐ˜ํ™˜๊ฐ’์œผ๋กœ ์ดํ„ฐ๋ ˆ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

Symbol.iterator ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ง„ ๊ฐ์ฒด๋ฅผ ๋ฐ˜๋ณต ๊ฐ€๋Šฅ(์ดํ„ฐ๋Ÿฌ๋ธ”, iterable)ํ•œ ๊ฐ์ฒด๋ผ๊ณ  ํ•œ๋‹ค.

8.11.4 ์ œ๋„ˆ๋ ˆ์ดํ„ฐ

์ œ๋„ˆ๋ ˆ์ดํ„ฐ ์˜ ์„ฑ์งˆ์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค

  • ๋ฐ˜๋ณต ๊ฐ€๋Šฅํ•œ ์ดํ„ฐ๋ ˆ์ดํ„ฐ๋ฅผ ๊ฐ’์œผ๋กœ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  • ์ž‘์—…์˜ ์ผ์‹œ ์ •์ง€์™€ ์žฌ์‹œ์ž‘์ด ๊ฐ€๋Šฅํ•˜๋ฉฐ ์ž์‹ ์˜ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•œ๋‹ค.

์ œ๋„ˆ๋ ˆ์ดํ„ฐ ์ •์˜์™€ ์‹คํ–‰

function* gen() {
  yield 1;
  yield 2;
  yield 3;
}
var iter = gen();
console.log(iter.next()); // Object {value:1, done:false}
console.log(iter.next()); // Object {value:2, done:false}
console.log(iter.next()); // Object {value:3, done:false}
console.log(iter.next()); // Object {value:undefined, done:true}

์œ„์˜ ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰ ๊ณผ์ •์„ ์‚ดํŽด๋ณด๋ฉด

  1. ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ํ•จ์ˆ˜์ธ gen์€ ๋ฐ”๋กœ ์‹คํ–‰๋˜์ง€ ์•Š๊ณ  ์ดํ„ฐ๋ ˆ์ดํ„ฐ๋ฅผ ๋ณ€์ˆ˜ iter์— ๋Œ€์ž…ํ•œ๋‹ค.
  2. ์ดํ„ฐ๋ ˆ์ดํ„ฐ์˜ next ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด ์ฒซ ๋ฒˆ์งธ yield ์—ฐ์‚ฐ์ž์˜ ์œ„์น˜๊นŒ์ง€ ์‹คํ–‰ํ•˜๊ณ  ๊ฒฐ๊ด๊ฐ’์œผ๋กœ ์ดํ„ฐ๋ ˆ์ดํ„ฐ ๋ฆฌ์ ˆํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ์ด๋•Œ ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ํ•จ์ˆ˜์˜ ๋‚ด๋ถ€ ์ฒ˜๋ฆฌ๋Š” yield 1์—์„œ ์ผ์‹œ ์ •์ง€ ์ƒํƒœ๊ฐ€ ๋œ๋‹ค.
  3. ๋˜ ๋‹ค์‹œ ์ดํ„ฐ๋ ˆ์ดํ„ฐ next ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด ์ผ์‹œ ์ •์ง€ํ•œ ์œ„์น˜์— ์žˆ๋Š” ์ฒ˜๋ฆฌ๋ฅผ ์žฌ๊ฐœํ•œ๋‹ค. ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ value ํ”„๋กœํผํ‹ฐ์™€ done ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ€์ง„ ์ดํ„ฐ๋ ˆ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์ฒ˜๋ฆฌ๋ฅผ ์ผ์‹œ ์ •์ง€ ํ•œ๋‹ค.
  4. 3๊ณผ ๋™์ผ
  5. ๋งˆ์ง€๋ง‰ yield์— ๋„์ฐฉํ•˜๊ณ , ์ดํ„ฐ๋ ˆ์ดํ„ฐ ๋ฆฌ์ ˆํŠธ์ธ value ํ”„๋กœํผํ‹ฐ ๊ฐ’ undefined์™€ done ํ”„๋กœํผํ‹ฐ ๊ฐ’์ธ true๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

์ œ๋„ˆ๋ ˆ์ดํ„ฐ์— ๊ฐ’ ๋„˜๊ธฐ๊ธฐ

function* fibonacci() {
  var fn1 = 0,
    fn2 = 1;
  while (true) {
    var fnew = fn1 + fn2;
    fn1 = fn2;
    fn2 = fnew;
    reset = yield fn1;
    if (reset) {
      (fn1 = 0), (fn2 = 1);
    }
  }
}
var iter = fibonacci();
for (var i = 0; i < 10; i++) {
  console.log(iter.next().value); // 1,1,2,3,5 ... 55 ์ˆœ์„œ๋Œ€๋กœ ์ถœ๋ ฅ
}
console.log(iter.next().value); // 89
console.log(iter.next(true).value); // 1
console.log(iter.next().value); // 1
console.log(iter.next().value); // 2
profile
FrontEnd Developer

0๊ฐœ์˜ ๋Œ“๊ธ€