void(document.body.innerText += 'hi')
eval(document.body.innerText +='\nbye')
Function(document.body.innerText += '\n!!!')
void(Function(function foo(){document.body.innerText += '\n>hi2'; return true}).toString())();
eval(Function(function foo(){document.body.innerText += '\nbye2'; return true}).toString())();
Function(Function(function foo(){document.body.innerText += '\n!!!2'; return true}).toString())();
在这些不同的语句中执行代码的处理模型是什么?
void(alert('hi'))
undefined
eval(alert('hi'))
undefined
Function(alert('hi'))
function anonymous() {
undefined
}
eval(Function(function foo(){return true}).toString())();
TypeError: undefined is not a function
void(Function(function foo(){return true}).toString())();
TypeError: string is not a function
Function(Function(function foo(){return true}).toString())();
undefined
答案 0 :(得分:3)
在this article中解释了eval
和Function
构造函数:
(...)全局内置
eval
函数评估a范围内的代码 呼叫者强>从
Function
构造函数创建的函数内执行的代码 并不真正在全球范围内执行。但是,它不会执行 当地范围,这可能导致混乱。Function
构造函数创建一个范围链包含的函数 除了全局范围之外(在函数自己的激活之前) 对象,当然)。通过创建的函数中包含的任何代码Function
构造函数在该函数的范围内计算,而不是在 全球范围。但是,它几乎就像代码全局执行一样 全局对象是范围链中的下一个对象。
根据this page,void
只返回undefined
:
在许多语言中,
void
是一种没有值的类型。在JavaScript中,void
是一个运算符,它接受一个操作数并返回undefined
。这个 没有用,而且非常令人困惑。避免使用void
。
答案 1 :(得分:1)
以下是评估差异的摘要:
void
评估包含函数范围中的代码eval
计算包含函数范围中的字符串Function
评估自己范围内的代码和回报差异:
void
始终返回undefined eval
返回已执行代码的返回值Function
返回匿名函数<强>参考强>
答案 2 :(得分:0)
值得注意的是你完全滥用这些功能。
void
只是评估一些表达式并返回undefined。
注意它是一个操作符而不是一个函数,所以不需要将操作符包装在括号内。
如果您担心undefined
可能被遮挡,或者您想要输入较少的字符,这仅对于获取未定义的值非常有用。
而不是
var undef = void(document.body.innerText += 'hi')
更好地使用
document.body.innerText += 'hi';
var undef = void 0;
如果您不需要定义,请不要使用void
。
eval
应该用字符串调用。它将该字符串计算为代码。确切的行为取决于您是以严格模式还是以草率模式调用它,以及它是直接呼叫还是间接呼叫。
如果你不用字符串调用它,它只会返回参数。
在您的情况下,eval(document.body.innerText += '\nbye')
将:
document.body.innerText += '\nbye'
,返回新值,例如"hello\nbye"
。我几乎确定eval(document.body.innerText +='\nbye')
不是您想要的,但这是一个(不推荐)反例:
var myvar = 0;
var bye = 123
eval(document.body.innerText += '\nbye');
console.log(myvar); // 123
&#13;
myvar =
&#13;
Function
构造函数基本上类似于eval
,但它创建了一个函数,而不是立即将字符串作为代码运行。
document.body.innerText += '\n!!!'
无法返回有效字符串,因此只会抛出。
然后你有一些奇怪的混合这些功能。
如果将函数传递给Function
构造函数,它将被字符串化。 Function
构造函数将返回一个匿名函数,该函数只声明一个类似参数的函数。这毫无意义。
如果您拨打toString
,则会对匿名函数进行字符串化。
然后,void(Function(function foo(){document.body.innerText += '\n>hi2'; return true}).toString())();
将尝试调用此字符串化。但字符串不可调用。错误。
eval(Function(function foo(){document.body.innerText += '\nbye2'; return true}).toString())();
将评估字符串化。为什么?但函数声明不会返回一个值,因此您将获得未定义的,这是不可调用的。错误。
Function(Function(function foo(){document.body.innerText += '\n!!!2'; return true}).toString())();
将字符串化foo
,将其解析为匿名函数,对匿名函数进行字符串化,然后再将其解析为另一个匿名函数。请不要这样做。最后,调用将返回undefined,因为那里没有return语句。