Javascript 在一行中多次调用函数
我很好奇为什么:Javascript 在一行中多次调用函数,javascript,Javascript,我很好奇为什么: (function () { return 'one' })()() 返回: TypeError: (intermediate value)(...) is not a function 而不是: TypeError: 'one' is not a function 错误消息使用变量名或其他标识来说明什么不是函数。因为返回值没有分配给任何对象,所以它没有标识符,所以引擎会显示中间值,因为在大括号中时(函数(){return'one'})成为产生中间结果的表达式,并且这些
(function () { return 'one' })()()
返回:
TypeError: (intermediate value)(...) is not a function
而不是:
TypeError: 'one' is not a function
错误消息使用变量名或其他标识来说明什么不是函数。因为返回值没有分配给任何对象,所以它没有标识符,所以引擎会显示中间值,因为在大括号中时(
函数(){return'one'}
)成为产生中间结果的表达式,并且这些结果尚未绑定到变量
根据,
规范类型值是不支持的规范人工制品
必须对应于ECMAScript中的任何特定实体
实施
规范类型值可用于描述中间结果
ECMAScript表达式求值的值,但无法存储此类值
作为对象的属性或ECMAScript语言变量的值
报告解释说:
出了什么问题?
它试图从函数中调用值,但该值实际上不是函数。有些代码希望您提供一个函数,但这并没有发生
它还提供了一些触发此错误的代码示例以及它们报告的实际错误消息。我不会在这里复制它们,但请仔细查看它们并注意它们生成的错误消息
实际错误消息中的“x”部分由预期为函数而非函数的对象的名称替换
由于本例中的对象没有名称(它是在表达式求值期间计算的中间结果,请参见下面的说明),因此引擎无法报告其名称,并尝试尽可能提供帮助。它报告“(中间值)(…)”可能是因为这样更具描述性;它是一个函数返回的值,该函数未存储,但用于计算另一个值
它不能报告实际值,因为中间值可以是任何值;如果它是一个复杂的数据结构,那么错误消息将变得臃肿,而不会添加太多信息
显然,我从第一次开始就不理解这个问题,下面是我的初始答案,它解释了为什么会产生错误,而不是为什么错误消息是这样的,而不是OP所期望的
此代码
(function () { return 'one' })()()
function () { return 'one' }
(function () { return 'one' })()
(function () { return 'one' })()()
'one'
)
在步骤3中,代码的效果与调用'one'()
相同。这与one()
(如您所想)不同
错误消息中引用的中间值是第一次函数调用返回的字符串,然后在表达式中使用(作为函数),而不保存在变量中(这是对“中间”措辞的解释)
正如错误消息明确指出的那样,'one'
不是函数,尝试将其用作函数(通过在表达式中放置第二对括号)是行不通的
为了使其工作,在步骤#1上创建的匿名函数必须返回另一个(匿名)函数,如下所示:
(function() { return function() { return 'one'; } })()()
现在,调用outer函数时,它返回一个匿名函数,该函数与原始代码在步骤#1中创建的匿名函数类似。调用此函数(第二个()
)时,它返回字符串“one”
这可能不是你想要的。只有使用
eval()
才能调用名为string的函数,这是最好避免的语言特性(有几个明显的原因)。有趣的问题:)如果您指定了函数,比如f
,我们得到了未捕获的TypeError:f(…)不是函数<代码>中间值
似乎来自函数是匿名的,但错误消息就像第一次调用没有真正计算过一样。函数返回一个字符串。执行后,第二个函数调用将是'one'()
,它与one()
不同(正如您可能想要的)。好的,但是'one'只是一个字符串,它没有分配给任何对象,或者我错了吗?@Src是的,它只是一个字符串,不是一个变量。这是因为它没有分配给任何东西,引擎吐出的是中间值,而不是名称。我不知道这为什么会被否决。这是一个比我更好的答案。事实上,我还认为在第3步中,代码的效果与调用“一”(one)是一样的。但事实并非如此。这就是我的问题所在!我想我第一次就不明白你的问题。我更新了答案。