Created
March 12, 2019 06:18
-
-
Save Ding-Fan/7e15c4c26828976774d380504ee49179 to your computer and use it in GitHub Desktop.
interview
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 首先来看一些 pure function | |
(x) => x | |
// 这个 function 只用了一个 x ,并且这个 x 是 bound 在这个 function 的 scope 里的 | |
(x, y) => { | |
const z = 8 | |
return x + y + z | |
} | |
// 这个 function 用到了 x , y , z 。这三个家伙都是 bound 在这个 function 的 scope 内的。 | |
// 这些 pure function 无论何时何地调用,你都明确的知道它会做什么。 | |
// 前方高能: | |
(x) => x + y | |
// 这个就不一样了。谁都不知道这个 y 是什么。这个 y 就被称作 free variable 。 | |
// https://www.wikiwand.com/en/Free_variables_and_bound_variables | |
// In computer programming, the term free variable refers to variables | |
// used in a function that are neither local variables nor parameters | |
// of that function. The term non-local variable is often a synonym in | |
// this context. | |
// 所以我们就可以认为 | |
// - Functions containing no free variables are called pure functions. | |
// - Functions containing one or more free variables are called closures. | |
// 那么 closure 有什么用途呢? | |
// 拿上面用到的 monster 来看 | |
function monster (a) { | |
// 我们用到的 theArguments 和 sourceLength 和 sourceFunction 都是 free variable | |
// 也就是说, closure 的一个用途就是,把一些需要多次或者不同时间去取用、操作的数据给保存起来。 | |
theArguments.push(a) | |
if(theArguments.length === sourceLength) { | |
return sourceFunction(...theArguments) | |
} else { | |
return monster | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function currying(sourceFunction) { | |
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/length | |
// 用 Function.length 去拿 sourceFunction 的 arguments 数量,并存为 sourceLength 方便对比的时候用 | |
const sourceLength = sourceFunction.length | |
// theArguments 用来存将要传入的 arguments | |
const theArguments = [] | |
// 这里就像一个贪吃的 monster 一样,非要吃饱才给结果 | |
function monster (a) { | |
// 先把传入的参数吃掉(放到 theArguments 里存起来) | |
theArguments.push(a) | |
// 看看吃饱了没 | |
if(theArguments.length === sourceLength) { | |
// 吃饱了,给结果。 | |
return sourceFunction(...theArguments) | |
} else { | |
// 没吃饱,还要吃。 | |
return monster | |
} | |
} | |
return monster | |
} | |
function add(a, b) { | |
return a + b | |
} | |
// add(1, 2) -> curring(add)(1)(2) | |
const stepA1 = currying(add) | |
const stepA2 = stepA1(1) | |
const stepA3 = stepA2(2) | |
console.log(stepA1) | |
console.log(stepA2) | |
console.log(stepA3) // -> 2 | |
function addMore(x, y, z, foo, bar) { | |
return x + y + z + foo + bar | |
} | |
// addMore(1, 1, 2, 3, 5) -> curring(addMore)(1)(1)(2)(3)(5) | |
const stepB1 = currying(addMore) | |
const stepB2 = stepB1(1) | |
const stepB3 = stepB2(1) | |
const stepB4 = stepB3(2) | |
const stepB5 = stepB4(3) | |
const stepB6 = stepB5(5) | |
console.log(stepB1) | |
console.log(stepB2) | |
console.log(stepB3) | |
console.log(stepB4) | |
console.log(stepB5) | |
console.log(stepB6) // -> 12 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment