JavaScript:函数执行的顺序

时间:2016-12-06 22:48:08

标签: javascript node.js ecmascript-6 ecmascript-5 ecmascript-7

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

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

try{
  e();
}catch(a){
  e();
}

花了一些时间来了解每个变量(此处常量)的含义。我开始分析e()内部try块中的代码。因此,e表示闭包,这意味着将使用参数d调用函数c(0)e将变为1。据我了解,这里d基本上代表console.log函数(但我无法弄清楚为什么他们使用bind?)。

现在,我知道第一个将被执行c(0)然后结果被提交到控制台,对吧?让我们看一下函数c。它返回转换为字符串的第一个参数和a.a(b())的连接结果。好的,所以a.a(b())将首先执行,我是对的吗?但是,问题是因为a.a不是函数,它是未定义的,所以会抛出错误,我们转到catch

现在,在catch块中,所有内容都应该相同,因此a.a仍然不是函数,应抛出引用错误。但是,当我看到没有抛出任何错误时,它让我感到惊讶,但是控制台实际上记录了1undefined。为什么?怎么样?

好的,经过一番思考后,我意识到可能在调用a.a(b())时可能会先执行b()。按照我的假设,然后函数b asign引用一个对对象a的属性a什么都不做的函数,对吗?但是,a.a是一个函数,它将在try块中执行,0undefined将被记录。

然而,这两个假设都不正确。这里的主要问题是首先执行的是什么?如果我们致电someObject.propertyWhichIsNotAFunction(somethingWhichMakesItAFunction),会发生什么?首先执行什么?似乎在try块中,首先执行一件事,然后在catch其他事件中执行。这对我来说毫无意义。有什么解释吗?

1 个答案:

答案 0 :(得分:1)

这与Why is the value of foo.x undefined in foo.x = foo = {n: 2}?的原因非常相似,只是有点棘手,因为它在执行时抛出TypeError时依赖它。

基本上会发生什么:

    评估
  1. a.a以找出稍后在步骤3 中将被称为的函数。
  2. b()被评估,因为它是一个函数参数及其返回 value成为a.a评估到的任何内容的实际参数。
  3. 执行步骤1中评估为a.a的任何内容,并以b()的返回值作为参数。
  4. 规范的相关部分在这里:https://www.ecma-international.org/ecma-262/7.0/index.html#sec-function-calls

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

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

    这意味着评估a.a并将其引用的函数称为func。第一次a.a评估为undefined,因此funcundefined,并且https://www.ecma-international.org/ecma-262/7.0/index.html#sec-evaluatedirectcall的第2步会引发TypeError,这是 ArgumentListEvaluation(arguments)后,调用b()并为a.a分配新值,但不会在func的值之后