高阶函数 - 雄辩的Javascript

时间:2017-12-12 23:48:29

标签: javascript

有人可以帮我理解下面的例子。我觉得我非常接近它,但有些事情并没有点击。我对这些函数之间的关系感到困惑,特别是在没有先定义它的情况下如何存在大量的10(11)。

function greaterThan(n) {
  return function(m) { return m > n; };
}
var greaterThan10 = greaterThan(10);
console.log(greaterThan10(11));

任何朝着正确方向的推动都将不胜感激! JH

2 个答案:

答案 0 :(得分:0)

greaterThan会返回一个函数,当您调用它时会指定n。它返回的函数接受一个参数,如果该参数大于n,则返回true。

调用greaterThan(10)会返回如下函数:

  function greaterThan10(m) {
    var n = 10;
    return m > n;
  }

答案 1 :(得分:-1)

函数式语言将函数视为一等公民,它们不仅存在于源代码中并被编译掉,它们是一个真实的原语,可以实例化,存储和传递,就像字符串或布尔等一样,增加了调用它们来运行例程的能力。

高阶函数通常被命名为,因为它接受函数作为参数,或者返回一个新函数本身,并且通常用作抽象,组合,修饰或绑定/部分应用函数的方法。

在这种情况下,它返回一个修饰函数。本质上它是一个工厂,它创建一个全新的函数实例,其中提供的数字在运行时烘焙,而不是在编写时手动分配n,它是在调用HOC时提供的。< / p>

为了解释它如何更好地工作,让我们回到你编写命名函数时实际发生的事情......

function foo(buzz) { 
  console.log(buzz) 
} 

它创建对Function实例的引用,并将其分配给名为foo

的变量

构造函数可以更好地说明这一点(范围不同,但是另一个时间)......

const foo = new Function('buzz', 'console.log(buzz)')
foo('boom!') // logs 'boom!'

或者通过为匿名函数指定一个变量(范围不同但这里不重要)......

const foo = function(buzz) {
  console.log(buzz) 
}
foo('shackalacka') // logs 'shackalacka'

此Function实例具有您指定的例程,并且可以通过引用名称调用,即变量名称为foo,因此您可以通过foo('Nic Cage')调用它来执行它的例程。但它只是一个引用,所以你可以将它重新分配给任何其他名称const bar = foo并通过它调用它完全相同的Function实例...

foo('boom!') // logs 'boom!'
const bar = foo
bar('boom!') // logs 'boom!'

因为它们是同一个实例,所以它们是相同的参考...

bar === foo // => true

TLDR 函数是一个真实的对象实例,可以动态创建,并通过引用传递

HOC通过返回一个全新的Function实例更进一步,该实例未在代码中直接由您完全定义,并且尚未绑定到变量,因此可以在运行时进行分配。这也使它能够使用在编写它时未知的任何变量传递给它(在本例中为n),此时它将被锁定到提供的值。如果提供n = 10,那么在程序表面下,程序只是在运行时为您执行以下操作...

cont greaterThan10 = new Function('m', 'return m > 10')

在现实世界中,HOC就像编写用于生成更多馅饼食谱的配方。一旦你制作了糕点配方以及如何制作馅饼形状,外面的馅饼配方总是相同的,但可以有一些不同的糕点类型,以及你当时的感觉。作为“另一天的馅饼”的厨师#39;餐厅,确保你每次在菜单上都有一个新的馅饼,你可以找到你的馅饼配方和糕点配方,复印它们,把它们交给你的厨师并告诉他们只是将它们组合在一起并添加填充物,但它们没有经验并且所有人都需要完全相同的全牛肉酥饼配方副本,否则将是一场灾难!通用馅饼的HOC允许您为特定糕点配方的馅饼生成配方(但不填充),当您通过灌装时,它将为该特定灌装生成新的配方,您可以保存以供日后使用使用,写下一次,并给你的厨师!

// I'm an exec chef and cleverly worked out a recipe that can make ANY pie with any pastry I want later without lifting a finger! 
function pieRecipe(pastryRecipe) {
  return function(filling) {
    pastryRecipe() + mashedUp(filling) + pastryRecipe() // this returns a further recipe for any pie with this pstry type
  }
}
const chouPieRecipe = pieRecipe(chouPastryRecipe) // any pie can now be made with chou pastry
const beefPieRecipe = chouPieRecipe('beef') // yay saved recipe for beef chou pie, now the exec chef can go do some daytime TV show
const beefPieLunch = beefPieRecipe() // yum customer loves it
const anotherBeefPieLunch = beefPieRecipe() // blurgh too much beef pie
// "err waiter, excuse me I need something for my indigestion!" 
// sous chef: "oh look Chef left his generic pie recipe lying around, but we have no chou left, hang on heres a recipe for shortcrust pastry, I can make you...."
const medicinePieLunch = pieRecipe(shortCrustRecipe)('indigestion tablets')() // just make me the actual pie right now, but lets not save the recipe, its gross!!