JavaScript:“x(x)(v)”语法是什么意思?

时间:2017-06-09 15:18:06

标签: javascript

Book "core concepts" chapter outline上阅读并享受Eric Elliot的函数式编程方法时,我决定重新审视箭头函数。考虑到这一点,我在Jason Orendorff'necessity of type checking'发现了一篇关于MDN Hacks的2015年文章。在文章的最后,我遇到了lambda-calculus示例,使用箭头函数转换为ES6,如下所示:

这是一个数学家可以使用Church的λ表示法编写的“程序”的例子:

fix = λf.(λx.f(λv.x(x)(v)))(λx.f(λv.x(x)(v)))

等效的JavaScript函数如下所示:

var fix = f => (x => f(v => x(x)(v)))
               (x => f(v => x(x)(v)));

我还应该补充一点,我在代码上尝试了Babel转换器,它仍然返回与x(x)(v)中相同的语法:

var fix = f => (x => f(v => x(x)(v)));

被转换为

"use strict";

var fix = function fix(f) {
  return function (x) {
    return f(function (v) {
      return x(x)(v);
    });
  };
};

困扰我的部分是function (v) { return x(x)(v) }部分,尤其是x(x)(v)?这种语法是什么意思?

我必须有一些简单的东西,但我似乎无法在任何地方找到答案。非常感谢您的建议。谢谢!

2 个答案:

答案 0 :(得分:1)

x(x)(v)是两个链式函数调用。 x(x)返回一个函数,然后使用v作为参数调用该函数。这相当于:

const y = x(x);  // y is a function
y(v);

具体例子:

const x = function(foo) { return function(bar) { console.log(bar); } };
const y = x(x);
y(v);

答案 1 :(得分:0)

在对该语法究竟是什么以及它如何正常工作的主题进行更多研究后,我发现x(x)(v)仅仅是IIFE(立即调用函数表达式)。我相信巴贝尔不会透露它,因为它是遗留的记谱法。正如詹姆斯在对原始问题的评论中提到的那样“这种行为自很久以前就已经在javascript中出现了。”

如果您想了解更多信息,您只需知道上述内容即可正确说出您的搜索内容。尽管至少可以说MDN's page on IIFEs,但那里提到的“快速例子”应该引导你朝着正确的方向前进。因此,在使用“Passing Arguments to IIFE”之前的stackoverflow以及带有“What are the end-parameters of an immediately-invoked function expression for?”的quora上回答了类似的问题。

这个特定问题“什么是x(x)(v)语法?”会让大多数人失望的部分?是x(x)周围没有括号,如下所示:

x(x)(v) == (x(x))(v)

现在这完全不同了,大多数人现在都会马上知道,(v)只是x(x)IIFE的一个参数。

对于最简单的示例,只需尝试这段代码:

function x (val) {return (val)};

var v = "v_variable";

console.log(x(x)(v));

或此片段:

function x (val) {return (val)};

function fix (v) {
  var v = "I am the result variable, successfully returned by the x(x)(v) IIFE";
  return x(x)(v)
//  return (x(x))(v)
};

document.getElementById("demo").innerHTML = fix();
<!DOCTYPE html>
<html>
<body>

<h3>Ivoking x(x)(v) IIFE returns the same result as the generally accepted and widely known (x(x))(v) IIFE notation</h3>

<p id="demo"></p>

</body>
</html>