【问题标题】:How does that implicit passing of function arguments in Javascript work?Javascript 中函数参数的隐式传递是如何工作的?
【发布时间】:2021-06-26 21:33:27
【问题描述】:

我最初来自 Java 编程语言作为背景。 Java 是强类型的并且非常明确(我的意思是,你必须把事情写出来,你不能只是省略它们)。我永远不会想到的一件事是传递给 javascript 的隐式参数是如何工作的......

举个例子:

const observer = {
    next: console.log,
    error: console.error,
    test: console.table,
}

observer.next('HI World!')

接下来,我指定 console.log 是一个函数,但我从来没有说过要接受一个值,但在 Javascript 中,我显然可以将任何东西作为后缀扔给函数,并将其作为函数的参数。 这也是流水线或柯里化的基本工作原理,它将剩余的返回值作为参数..为什么会这样?

其次,例如在 express 中,我有一个这样的函数签名:

app.get('/', function (req, res) {
  res.send('GET request to the homepage');
});

我实际上是从我的函数回调中得到 req 和 res 的,对吗?这些不是我传递给回调函数的参数吗?

编辑:有人可以再次向我解释REQRES参数的来源吗?这个结构是如何工作的?因为我自己定义了回调函数,但不是将 req 和 res 作为参数传递给我的回调,它们似乎是从某个地方传递回我的回调函数内部的?!?!

【问题讨论】:

  • 这是三个独立的概念。 1. observer.next 现在本质上是 is console.log,因此您可以调用两者中的任何一个来获得相同的结果。无论您传递给observer.next 调用的任何参数最终都会传递给console.log,就这么简单。 2. currying 不会“获取剩余的返回值”。当您有 const f = a => b => a + b; 时,f(...)f(3)(...) 都只查看第一个参数。 3. 不是调用函数并向其传递参数,而是提供一个由库调用的函数。 express 在调用时传入其RequestResponse
  • 好吧,控制台是另一个具有log 方法的对象,您刚刚将该方法(函数)分配给您的观察者对象next 属性,然后稍后调用该日志方法,该方法接受一些参数.不知道这里有什么令人困惑的地方。
  • 将您在示例中对.next() 的调用视为Java 中的方法参考,它本质上是做同样的事情:APrinter aPrinter = System.out::println;
  • 关于 express 部分,是的,您提供的回调将在 app.get 方法中的某个时刻被调用,并且 express 将传递这些请求和响应对象,这意味着您可以在回调中使用它们。跨度>
  • 在任何地方都没有隐式传递参数。在调用函数的地方,调用语法非常明确。我认为您实际上缺少的是functions are first-class values

标签: javascript callback parameter-passing


【解决方案1】:

JavaScript 中的函数是一个对象,就像任何其他对象一样。这意味着一个函数可以被传递,可以分配给变量,并且基本上可以在任何可以使用值的地方使用。这被称为一等函数

例如,给定一个像这样的简单函数:

function log(msg) {
  console.log(msg);
}

这两个函数在概念上是等效的:

const log1 = log;

// same as

function log1(msg) {
  log(msg);
}

如您所见,我们可以直接将函数log赋值给log1这样的变量,然后我们就可以像使用log一样使用log1

log1('foobar');

一等函数的另一个用途是能够将它们作为参数传递给其他函数。像您的 Express 示例中那样接受回调的函数称为 高阶函数。回调的参数由该回调的调用者提供。在您的情况下,Express 提供了 reqres 参数。

使用回调是控制反转的一种形式。您正在将程序那部分的控制权传递给调用者。

【讨论】:

  • 好的,这是否意味着,在我的应用程序对象中,有一个带有签名的“get”方法:get(path, cb){ doSomething(path);... create req and res object ... cb(req,res)?所以在我的get方法体中,我有传递给我的回调的req和res,以便在我传递给该get方法的回调函数中使用它们? ;) 不知何故相当混乱......
猜你喜欢
  • 1970-01-01
  • 2020-09-07
  • 2020-11-10
  • 1970-01-01
  • 1970-01-01
  • 2020-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多