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。
基本上会发生什么事情是:
-
aa
进行评估,以确定稍后在步骤3中将调用哪个函数。 -
b()
被评估,因为它是一个函数参数,其返回值成为无论评估的实际参数。 - 无论在步骤1中评估的是以
b()
的返回值作为参数执行的。
规范的相关部分在这里: https : //www.ecma-international.org/ecma-262/7.0/index.html#sec-function-calls
请注意,调用函数时发生的第一件事是:
- 让ref是评估MemberExpression的结果。
- 让func成为? 的GetValue(REF)。
这意味着aa
被评估,它所指的函数被称为func
。 第一次评估undefined
,所以func
是undefined
并且在https://www.ecma-international.org/ecma-262/7.0/index.html#sec-evaluatedirectcall的第2步将抛出TypeError 在 ArgumentListEvaluation(arguments)
,它调用b()
并为aa
分配一个新的值,但不在func
的值之后。