์๋ฐ์คํฌ๋ฆฝํธ ํจ์๋ Function ๊ฐ์ฒด๋ค. ๋ค์๊ณผ ๊ฐ์ ํน์ง์ด ์๋ค.
- ํจ์๋ ๋ณ์๋ ํ๋กํผํฐ๋ ๋ฐฐ์ด ์์์ ๋์ ํ ์ ์๋ค.
- ํจ์๋ ํจ์์ ์ธ์๋ก ์ฌ์ฉํ ์ ์๋ค.
- ํจ์๋ ํจ์์ ๋ฐํ๊ฐ์ผ๋ก ์ฌ์ฉํ ์ ์๋ค.
- ํจ์๋ ํ๋กํผํฐ์ ๋ฉ์๋๋ฅผ ๊ฐ์ง ์ ์๋ค.
- ํจ์๋ ์ด๋ฆ ์๋ ๋ฆฌํฐ๋ด๋ก ํํ ๊ฐ๋ฅํ๋ค. (์ต๋ช ํจ์)
- ํจ์๋ ๋์ ์ผ๋ก ์์ฑํ ์ ์๋ค.
์ด๋ฌํ ์์
์ด ๊ฐ๋ฅํ ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌ์ผ ์ผ๊ธ ๊ฐ์ฒด ๋ผ๊ณ ํ๋ฉฐ ์ผ๊ธ ๊ฐ์ฒด์ธ ํจ์๋ ์ผ๊ธ ํจ์ ๋ผ๊ณ ํ๋ค.
ํจ์์ ํ๋กํผํฐ
- caller : ํ์ฌ ์คํ ์ค์ธ ํจ์๋ฅผ ํธ์ถํ ํจ์
- length : ํจ์์ ์ธ์ ๊ฐ์
- name : ํจ์๋ฅผ ํ์ํ ๋ ์ฌ์ฉํ๋ ์ด๋ฆ
- prototype : ํ๋กํ ํ์ ๊ฐ์ฒด์ ์ฐธ์กฐ
Function.prototype์ ํ๋กํผํฐ
- apply() : ์ ํํ this์ ์ธ์๋ฅผ ์ฌ์ฉํ์ฌ ํจ์๋ฅผ ํธ์ถ. ์ธ์๋ ๋ฐฐ์ด ๊ฐ์ฒด
- bind() : ์ ํํ this์ ์ธ์๋ฅผ ์ ์ฉํ ์๋ก์ด ํจ์๋ฅผ ๋ฐํ
- call() : ์ ํํ this์ ์ธ์๋ฅผ ์ฌ์ฉํ์ฌ ํจ์๋ฅผ ํธ์ถ. ์ธ์๋ ์ผํ๋ก ๊ตฌ๋ถ
- constructor : Function ์์ฑ์์ ์ฐธ์กฐ
- toString() : ํจ์์ ์์ค ์ฝ๋๋ฅผ ๋ฌธ์์ด๋ก ๋ง๋ค์ด ๋ฐํ
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
ํจ์๋ฅผ ์ธ์๋ก ๋ฐ๋ ํจ์ ๋๋ ํจ์๋ฅผ ๋ฐํํ๋ ํจ์๋ฅผ ๋งํ๋ค. ๊ณ ์ฐจ ํจ์๋ ํจ์ํ ํ๋ก๊ทธ๋๋ฐ์ ํ ๋ ์์ฃผ ์ฌ์ฉํ๋ค. ๊ทธ ์๋ก๋ 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); // ๋ฌด์์ ์ํ๋ฒณ ๋ฌธ์์ด
ํจ์์ ํ๋กํผํฐ๋ฅผ ์ถ๊ฐํ๋ ๋ฐฉ๋ฒ์ผ๋ก ๊ฒฐ๊ณผ(๋ฐํ ๊ฐ)๋ฅผ ์บ์ฑํ์ฌ ๋ค์ ํธ์ถ ์์ ์ ๋ณต์กํ ์ฐ์ฐ์ ๋ฐ๋ณตํ์ง ์๊ฒ ํ๋ ํจํด์ 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));
}
ํจ์ 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));
};
}
์ธ์๋ฅผ ์ฌ๋ฌ ๊ฐ ๋ฐ๋ ํจ์์ ๋ช๋ช ์ธ์๋ฅผ ์์๋ก ์ง์ ํด์ ์๋ก์ด ํจ์๋ฅผ ์์ฑํ๋ ๊ธฐ๋ฒ
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๋ฅผ ์ธ์๋ก ๋๊ฒจ์ ํธ์ถ
์ธ์๋ฅผ ๋ ๊ฐ ์ด์ ๋ฐ๋ ํจ์๋ฅผ ๋ถํดํ์ฌ ์ธ์๊ฐ ํ๋์ธ ํจ์์ ์ค์ฒฉ ํจ์๋ก ๋ณํํ๋ ์์
var pow = function (exponent) {
return function (base) {
return Math.pow(base, exponent);
};
};
// ์ด๋ ๊ฒ ์ ์ํ ํจ์ pow๋ Math.pow๋ฅผ ์ปค๋งํ ๊ฒ์
Math.pow(base, exponent) = pow(exponent)(base);
๋ค๋ฅธ ํจ์์ ์ธ์๋ก ๋๊ฒจ์ง๋ ํจ์๋ฅผ ๊ฐ๋ฆฌ์ผ ์ฝ๋ฐฑ ํจ์
๋ผ๊ณ ํ๋ค.
15์ฅ์์ ๋ฐฐ์ธ ์ด๋ฒคํธ ์ฒ๋ฆฌ๊ธฐ addEventListener๋ ์ฝ๋ฐฑ ํจ์๋ฅผ ์ด๋ค.
f(g, ...) {
...
function f(callback, ...) {
...
callback();
...
}
}
- 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 ์ ๋๋ ์ดํฐ ์ฐธ๊ณ )
๋๋จธ์ง ๋งค๊ฐ๋ณ์
ํจ์์ ์ธ์๊ฐ ๋ค์ด๊ฐ๋ ๋ถ๋ถ์ ...์ ์
๋ ฅํ๋ฉด ๊ทธ๋งํผ์ ์ธ์๋ฅผ ๋ฐฐ์ด๋ก ๋ฐ๋๋ค.
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
์ดํฐ๋ ์ด์
์ดํฐ๋ ์ด์
์ ๋ฐ๋ณต ์ฒ๋ฆฌ ๋ผ๋ ๋ป์ผ๋ก ๋ฐ์ดํฐ ์์ ์์๋ฅผ ์ฐ์์ ์ผ๋ก ๊บผ๋ด๋ ํ์
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)
ํ ๊ฐ์ฒด๋ผ๊ณ ํ๋ค.
์ ๋๋ ์ดํฐ
์ ์ฑ์ง์ ๋ค์๊ณผ ๊ฐ๋ค
- ๋ฐ๋ณต ๊ฐ๋ฅํ ์ดํฐ๋ ์ดํฐ๋ฅผ ๊ฐ์ผ๋ก ๋ฐํํ๋ค.
- ์์ ์ ์ผ์ ์ ์ง์ ์ฌ์์์ด ๊ฐ๋ฅํ๋ฉฐ ์์ ์ ์ํ๋ฅผ ๊ด๋ฆฌํ๋ค.
์ ๋๋ ์ดํฐ ์ ์์ ์คํ
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}
์์ ํ๋ก๊ทธ๋จ ์คํ ๊ณผ์ ์ ์ดํด๋ณด๋ฉด
- ์ ๋๋ ์ดํฐ ํจ์์ธ gen์ ๋ฐ๋ก ์คํ๋์ง ์๊ณ ์ดํฐ๋ ์ดํฐ๋ฅผ ๋ณ์ iter์ ๋์ ํ๋ค.
- ์ดํฐ๋ ์ดํฐ์ next ๋ฉ์๋๊ฐ ํธ์ถ๋๋ฉด ์ฒซ ๋ฒ์งธ yield ์ฐ์ฐ์์ ์์น๊น์ง ์คํํ๊ณ ๊ฒฐ๊ด๊ฐ์ผ๋ก ์ดํฐ๋ ์ดํฐ ๋ฆฌ์ ํธ๋ฅผ ๋ฐํํ๋ค. ์ด๋ ์ ๋๋ ์ดํฐ ํจ์์ ๋ด๋ถ ์ฒ๋ฆฌ๋ yield 1์์ ์ผ์ ์ ์ง ์ํ๊ฐ ๋๋ค.
- ๋ ๋ค์ ์ดํฐ๋ ์ดํฐ next ๋ฉ์๋๊ฐ ํธ์ถ๋๋ฉด ์ผ์ ์ ์งํ ์์น์ ์๋ ์ฒ๋ฆฌ๋ฅผ ์ฌ๊ฐํ๋ค. ๋ง์ฐฌ๊ฐ์ง๋ก value ํ๋กํผํฐ์ done ํ๋กํผํฐ๋ฅผ ๊ฐ์ง ์ดํฐ๋ ์ดํฐ๋ฅผ ๋ฐํํ๊ณ ์ฒ๋ฆฌ๋ฅผ ์ผ์ ์ ์ง ํ๋ค.
- 3๊ณผ ๋์ผ
- ๋ง์ง๋ง 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