2017-05-22 51 views
0

它可能会感兴趣并节省几个小时,一个讨厌的捆绑问题,eval来自一个文件,函数来自第二个文件。eval不是函数

eval('console.log(0)') 
(function(x){console.log(x)})(1) 

将导致用:遗漏的类型错误:的eval(...)不是一个函数

,这是修复

eval('console.log(0)'); 
(function(x){console.log(x)})(1) 

失踪分号,我读过几倍大多数情况下,JS可以选择分号。

任何评论为什么eval不是这方面的函数?

+0

虽然分号插入是可选的。理解JS引擎何时实际插入一个分号是很好的。通过这个答案读取可能会有所帮助https:// stackoverflow。com/questions/2846283 /这是什么规则为JavaScript的自动分号插入ASI – Agalo

+0

从这里的教训总是把分号之间的文件分号:) – maciejW

回答

1

这是少数情况下Javascript的semicolon insertion将您启程的其中之一。

此代码:

eval('console.log(0)') 
(function(x){console.log(x)})(1) 

等效于此代码:

eval('console.log(0)')(function(x){console.log(x)})(1) 

换句话说,使用Javascript认为,表达eval('console.log(0)')评估的功能,你想用参数来调用(function(x){console.log(x)})。这显然不是你想要的,所以你需要在你的行尾添加分号。

3

JS运行时不适合猜测分号应该走到哪里。

当它看到这一点:

eval('console.log(0)') 
(function(x){console.log(x)})(1) 

它错误地假定立即调用函数表达式的结果是eval线(要传递到该eval计算结果为潜在功能的潜在可能参数的一部分)。

这里的时候,将工作的例子:

eval("(function(message){ alert(message); })") 
 
("Hi there!");

但是,你的情况,eval没有评估的功能,所以尝试失败传递一个说法,因此你的错误信息。

但是,它实际上与eval()实际上较少有关,特别是。这可以在任何时候在IIFE之前省略分号或者以(开始的任何表达式时弹出。

添加分号允许运行时知道IIFE是分开的。

规则是,您必须在任何行后面跟着((因为这是表达式的开始方式),以便让它们保持分离状态,从而插入分号。但是,更好的规则是不要依赖于自动分号插入,并始终将它们放入自己。

+0

这是我的猜测,但发现这是相当这是一种噩梦,因为这种代码不是手工编写的,所以它是许多第三方库的串联。 – maciejW

+1

@maciejW哦,顺便说一下,首先非常不鼓励使用'eval()'。它可能导致跨站脚本攻击,速度很慢并且在修改的范围链中运行。几乎总是有一种方法来重构代码,不需要'eval()'。 –