最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

What's the difference between void, eval, and the Function constructor in JavaScript? - Stack Overflow

programmeradmin2浏览0评论

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(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())();

What's the processing model for executing code within these different statements?

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
Share Improve this question edited Jan 28, 2016 at 20:53 Paul Sweatte asked Apr 27, 2012 at 1:16 Paul SweattePaul Sweatte 24.6k7 gold badges131 silver badges268 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 5

In this article the eval and Function constructors are explained:

(…) Global, built-in eval function evaluates code in the scope of a caller.

The code executed from within function created by Function constructor doesn’t really execute in global scope. However, it doesn’t execute in local scope either, which is what probably leads to confusion. Function constructor creates a function whose scope chain consists of nothing but a global scope (preceded with function’s own Activation Object, of course). Any code contained in a function created via Function constructor evaluates in a scope of that function, not in a global scope. However, it’s almost as if code executes globally, since global object is the very next object in the scope chain.

And according to this page, void just returns undefined:

In many languages, void is a type that has no values. In JavaScript, void is an operator that takes an operand and returns undefined. This is not useful, and it is very confusing. Avoid void.

Here is a summary of the evaluation differences:

  • void evaluates code in the containing function scope
  • eval evaluates strings in the containing function scope
  • Function evaluates code in its own scope

and the return differences:

  • void always returns undefined
  • eval returns the return value of the executed code
  • Function returns an anonymous function

References

  • JS101: The Function Constructor
  • JSLint Error Explanations: The Function constructor is eval
  • How Evil is Eval
  • [[Scope]] of functions created via Function constructor
  • Evaluating JavaScript code via eval() and new Function()
  • Gmail for Mobile HTML5 Series: Reducing Startup Latency - The official Google Code blog
  • Faster Loading Through Eval() – SproutCore
  • (down)Loading JavaScript as strings | High Performance Web Sites
  • Expressions versus statements in JavaScript - Dr. Axel Rauschmayer
  • The void operator in JavaScript

It's worth noting that you are pletely misusing these functions.

  • void just evaluates some expression and returns undefined.

    Note it's an operator and not a function, so no need to wrap the operant inside parentheses.

    This is only useful to get the value undefined if you worry undefined could be shadowed, or if you want to type less characters.

    Instead of

    var undef = void(document.body.innerText += 'hi')
    

    better use

    document.body.innerText += 'hi';
    var undef = void 0;
    

    And if you don't need to get undefined, don't use void at all.

  • eval is supposed to be called with a string. It evaluates that string as code. The exact behavior depends on whether you call it in strict or sloppy mode, and whether it's a direct or indirect call.

    If you don't call it with a string, it will just return the argument.

    In your case, eval(document.body.innerText += '\nbye') will:

    1. Run document.body.innerText += '\nbye', returns the new value, e.g. "hello\nbye".
    2. Evaluate the resulting text as code. Most probably this will throw.

    I'm almost sure eval(document.body.innerText +='\nbye') is not what you want, but here is a (not remended) counterexample:

    var myvar = 0;
    var bye = 123
    eval(document.body.innerText += '\nbye');
    console.log(myvar); // 123
    myvar =

  • The Function constructor is basically like eval, but it creates a function instead of running the evaluating the string as code immediately.

    document.body.innerText += '\n!!!' can't return a valid string, so it will just throw.

  • Then you have some strange mixes of these functions.

    If you pass a function to the Function constructor, it will be stringified. The Function constructor will return an anonymous function that will just declare a function like the argument. It's pointless.

    If you call toString, this will stringify the anonymous function.

    Then, void(Function(function foo(){document.body.innerText += '\n>hi2'; return true}).toString())(); will attempt to call this stringification. But strings are not callable. Error.

    And eval(Function(function foo(){document.body.innerText += '\nbye2'; return true}).toString())(); will evaluate the stringification. Just why? But function declarations don't return a value, so you will just get undefined, which is not callable. Error.

    And Function(Function(function foo(){document.body.innerText += '\n!!!2'; return true}).toString())(); will stringify foo, parse it to an anonymous function, stringify the anonymous function, and parse it again to another anonymous function. Please, don't do this. Finally, the call will return undefined because there is no return statement in there.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论