【问题标题】:What does this hight order function do?这个高阶函数有什么作用?
【发布时间】:2016-08-01 23:18:58
【问题描述】:

我的问题很简单,但我只是不知道我是否遗漏了什么。

为什么甚至需要 Arr 原型切片调用?

为什么甚至需要它,因为您只需将参数分配给 args 变量即可运行该函数。我知道它是一个类似数组的,但它没有来自它的方法

为什么arguments === func 是假的?

func.apply(null, args) 是如何工作的?

function logAndReturn(func) {  
  return function() {  
    var args = Array.prototype.slice.call(arguments);
    var result = func.apply(null, args);
    console.log('Result', result);
    return result;
  }
}
var addAndLog = logAndReturn(add);

【问题讨论】:

标签: javascript functional-programming


【解决方案1】:

您问了很多问题,其中大部分是重复的。但是,我知道有时很难拼凑许多不同的答案来找到您自己问题的答案。将来,您应该避免在帖子中提出比问题更多的问题。这会让一些人不那么生气。

我将在代码内联添加一些 cmets

function logAndReturn(func) { // <------------┐ 
  return function() { // <------------------┐ |
    // `arguments` belongs to this function-┘ |
    // NOT this one --------------------------┘
    var args = Array.prototype.slice.call(arguments);

    // `apply` expects an array but `arguments` is an object
    // we call `slice` on `arguments` so that it can be converted to an array
    var result = func.apply(null, args);

    console.log('Result', result);
    return result;
  }
}
var addAndLog = logAndReturn(add);

实际上,JavaScript 比这要宽容得多。它不是一种类型化的语言,所以当我说apply expects 一个数组时,我有点撒谎。当然,它会很好,但如果你给它一个 array-like 对象,它也不会哭泣

function theHiddenTruthBehindArguments() {
  console.log(arguments)
  console.log(arguments.length)
}

theHiddenTruthBehindArguments(0,1,'abc')
// {"0":0,"1":1,"2":"abc"}
// 3

arguments 实际上是一个类数组 对象。它具有连续的数字键(以 0 开头)和 length 属性,这是将任何对象视为数组所需的所有信息。

所以这实际上可以工作

function logAndReturn(func) {
  return function() {
    // this works too !
    var result = func.apply(null, arguments);
    console.log('Result', result);
    return result;
  }
}
var addAndLog = logAndReturn(add);

为了回答你的最后一个问题,apply 以非常简单的方式炒锅……

let args = [1,3,4]
func.apply(null, args)

…(大部分)与…相同

func(1,3,4)

这个你可以阅读欺骗问题。您可能需要了解一些细节。


你给出的那个函数可以在 ES6 中更好地表达,我认为它对你来说不会那么混乱

function logAndReturn(func) {

  // rest parameter ...args is the new way to express variadic functions
  // (functions that take a variable number of arguments)
  // all arguments given will be collected in a single `args` array
  return function(...args) {

    // spread syntax will expand the array to call `func`
    // with all of the collected args
    var result = func(...args)

    console.log('Result', result)
    return result
  }
}

【讨论】:

  • apply 可以直接与arguments 配合使用,因此splice 没有任何作用。 The documentation 明确指出它接受任何数组,例如 arguments 变量所在的对象
  • @Sylwester 谢谢,我正准备更新它。有时最基本的问题可能是最难回答的,嗯?
  • @Sylwester 现在我很好奇slice.call(arguments) 模式的来源。在 ES 历史上是否曾经有过 f.apply(null, arguments) 在没有实际 Array 对象的情况下无法工作的时候?
  • 你是对的。在 ES5 之前它需要是一个数组。
  • @Sylwester 谢谢。我不知道如何找到这些信息^_^
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-24
  • 1970-01-01
  • 2017-07-25
  • 2021-04-29
  • 2014-06-13
相关资源
最近更新 更多