JavaScript:函数执行的顺序

我正在学习JavaScript,但是有很多我无法理解的东西。 在一个在线JavaScript测验中,出现了以下问题:
以下JavaScript代码将login到控制台:

const a = {}; const b = () => aa = () => {}; const c = c => '' + c + aa(b()); const d = console.log.bind(console); const e = (e => () => d(c(e++)))(0); try{ e(); }catch(a){ e(); } 

我花了一些时间去了解每个variables(这里是常量)的含义。 我开始分析e()里面的try代码块的代码。 所以, e表示闭包,这意味着函数d将被调用参数c(0)e将变成1 。 据我了解,这里d基本上代表了console.log函数(但我不明白为什么他们使用bind ?)。

现在,我知道,第一个将被执行c(0) ,然后结果控制台,对不对? 让我们看看函数c 。 它返回第一个参数转换为string和aa(b())连接结果。 好的,所以aa(b())会先执行,对吗? 但是,问题是因为aa不是一个函数,它是不确定的,所以会抛出错误,我们去catch

现在,在catch块中应该是一样的,所以aa仍然不是一个函数,应该抛出引用错误。 但是,当我看到没有错误发生时,它让我感到惊讶,但是控制台实际上logging了1个1undefined 。 为什么? 怎么样?

好了,经过一番思考之后,我意识到也许在调用aa(b())也许b()会先执行。 按照我的假设,然后函数b将引用赋值给对象a属性a没有任何作用的函数,对吗? 但是,然后aa是一个函数,它将在try块中执行,并且0undefined将被logging。

但是,这两个假设都不是正确的。 这里的主要问题是先执行什么? 如果我们调用someObject.propertyWhichIsNotAFunction(somethingWhichMakesItAFunction) ,会发生什么? 什么是执行第一? 看来在try块中,一件事情是先执行,然后再catch其他事情。 对我来说真的没有意义。 任何解释?

这与foo.x = foo = {n:2}中的foo.x undefined的原因非常相似? ,只是有点棘手,因为它依赖于在执行中引发TypeError。

基本上会发生什么事情是:

  1. aa进行评估,以确定稍后在步骤3中将调用哪个函数。
  2. b()被评估,因为它是一个函数参数,其返回值成为无论评估的实际参数。
  3. 无论在步骤1中评估的是以b()的返回值作为参数执行的。

规范的相关部分在这里: https : //www.ecma-international.org/ecma-262/7.0/index.html#sec-function-calls

请注意,调用函数时发生的第一件事是:

  1. ref是评估MemberExpression的结果。
  2. func成为? 的GetValue(REF)。

这意味着aa被评估,它所指的函数被称为func 。 第一次评估undefined ,所以funcundefined并且在https://www.ecma-international.org/ecma-262/7.0/index.html#sec-evaluatedirectcall的第2步将抛出TypeError ArgumentListEvaluation(arguments) ,它调用b()并为aa分配一个新的值,但不在func的值之后。