preface

Eval () is a very useful function in JavaScript that can be dynamically executed as a string of code. However, various coding specifications and best practices strongly resisted Eval, almost putting it on death row, and Douglas Crockford, in his book the Essence of the JavaScript Language, called eval the worst of JavaScript. This article will reintroduce you to this function, why you don’t use it, and why you have to use it.

What is the eval

Before we examine eval’s pros and cons, let’s take a look at eval. It is unfair to judge a technology arbitrarily without knowing it.

Eval is a function on a global object that executes the string passed as JavaScript code. If the argument passed is not a string, it returns it unchanged. Eval is divided into direct calls and indirect calls. Usually, indirect calls perform better than direct calls.

When called directly, eval runs in the scope of the function it calls.

var context = 'outside';
(function(){
  var context = 'inside';  
  return eval('context'); }) (); //return 'inside'
Copy the code

In indirect calls, eval runs in the global scope.

var context = 'outside';
(function(){
  var context = 'inside';
  geval = eval;  
  return geval('context'); // The following two are also indirect calls //return eval.call(null, 'context');
  // return (1, eval) ('context'); }) (); //return 'outside'
Copy the code

Therefore, when called indirectly, Eval does not modify anything in the scope of the calling function. The JS interpreter has two modes, fast Path and slow path. When eval is called directly, the interpreter is in slow path. Because the scope is not controllable at this time, you need to listen to the whole scope, can not apply some of v8 compilation optimization, the corresponding compilation efficiency will be lower than fast Path.

Why not use eval

There are several reasons for resistance to Eval:

1. Performance degradation. The reason for this has already been mentioned. Some articles on the web even claim that eval() slows energy by a factor of 10.

2. Security issues. Because of its dynamic execution nature, it gives too much power to the evaluated string, leading to concerns about XSS and other attacks.

3. Debugging is difficult. Eval is like a black box, executing code that is difficult to debug with breakpoints.

For all these reasons, many people say eval is evil. In addition, Eval also has some friends, such as New Function, setTimeout, and setInterval. They also have the ability to execute a code string. The basic reason is that JS gives this method so much power that it is difficult for a novice to navigate, and it is easy to write questions without a good understanding of Eval. This is a bit like the GOto statement in C, which was also blocked because it had too many permissions.

Misunderstood eval

In fact, eval has always been misunderstood. It is probably one of the most powerful JavaScript functions out there, but it has been thrown out of favor by developers because of some misuse. Here’s my take on some of the most questionable points mentioned above.

The point about eval being 10 times slower comes from Engineer Mozila’s “Know Your Engines – How to Make Your JavaScript Fast.”

This is a talk published in 2011, and the JS engine has been optimized in various ways since then. Let’s test eval in action in a current JS engine. Again, use the figure above as the test case. The test environment is Node V8.11.1 and set the value of N to 10000.

When N = 10000, function performance with eval is more than 3 times slower than without eval, according to Benchmark. Set N to 1000000, and eval’s performance drops by a factor of 8.

We know from our tests that Eval does slow down function performance, and that performance slows down as the function grows. But in the general case (N < 1000000), the performance difference is not as dramatic as 10 times.

The problem with eval causing XSS attacks is not with eval, but with the data source. If the data source is inherently unreliable, XSS can occur even if you don’t use EVAL.

As for the third point, eval code is tricky to debug, but it’s not impossible. Eval code can be named by adding a line of “// @sourceURL =name” to the end of the code (browsers treat this special form of comment specially) so that it appears in the Sources panel and can be set for debugging.

Delicious warning

Eval is a great way to use it, even though everyone says it shouldn’t.

<div data-eval="data.count = data.count + 1">
    {{data.count}}
</div>
Copy the code

The rendered result is the eval evaluated value.

Eval is used by many libraries and frameworks to implement various forms of dark magic. Some of the earliest examples of eval parsing JSON, such as Douglas Crockford’s Json2.js (delicious! . Later, various MVVM frameworks, such as Vue and Avalon, used New Function, Eval’s gay friend, to evaluate expressions embedded in templates. To achieve the same effect as the above example, the difference is that these MVVM frameworks also need to parse the template to extract the parameters of the new Function.

Even when you can’t use eval, you have to make your own eval. For example, eval and new Function cannot be used in small programs, so if you want to dynamically inject and execute code, you need to take a big devolution and implement a JS Parser based on compilation principles.

conclusion

My personal opinion about Eval is that you don’t have to use it, but you have to understand it. The purpose of this article is not to recommend eval. As far as normal business development is concerned, Eval has little use. But on special occasions, eval is like a nuclear bomb.

If you have any questions or mistakes, please feel free to discuss them in the comments.


Reference links:

1.Global eval. What are the options?

2. Do I use Eval or Function in my MVVM framework implementations like Knockout, Vue and AvalonJS?

Eval () isn’t evil, just misunderstood

4.A new V8 is coming, Node.js performance is changing.

V8: Behind the Scenes (February Edition feat. A tale of TurboFan)