Skip to content

Instantly share code, notes, and snippets.

@Ding-Fan
Created March 12, 2019 06:18
Show Gist options
  • Save Ding-Fan/7e15c4c26828976774d380504ee49179 to your computer and use it in GitHub Desktop.
Save Ding-Fan/7e15c4c26828976774d380504ee49179 to your computer and use it in GitHub Desktop.
interview
// 首先来看一些 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
}
}
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