Join in and give eval a popular science.

Source: Internet
Author: User

In this article, I wanted to write more test cases. But a lot of tests have been done because of ash.

 

What is eval.

I personally think that the initial design of Eval is a built-in function that provides a dynamic executionCodeSo the description of ES3 is so simple. Here, to clearly describe ES3's eval code specifications, I have to come up with a large segment to explain these things.


ES3:

 

. Eval code: When the Controller enters an eval code execution environment, the previous (eval function call code) execution environment is used as the call environment to determine the scope chain. if the value of the variable object and the this keyword does not call the environment, the process of the scope chain, variable object, and this value is the same as that of global code. (The original description here is vague, so there is no calling environment, even if it refers to the global environment)
. The initialization of the scope chain is to include the same objects (activity objects, variable objects, and so on) in the same order, even those objects added with and catch ).. the variable object initialization process uses the variable object that calls the environment. but the identifier in the eval Code corresponds to the property. does not have any features. (This is why the variables declared in eval can be deleted by the delete operator)

The value of. This is the same as the value of this in the call environment. (In this case, Eval that is not called directly as defined in Edition 5 does not conflict with global call. In this case, its calling context is global context. Then this should point to global .)

 

Well, I must admit that this section looks like a loop. In short, the eval in ES3 is like the following:

1. It is a built-in function.

2. It has the ability to dynamically execute the content of a string as es code.

3. The scope of dynamic code execution is the location where the eval function is executed and the execution environment in which it is associated with the scope.

4. the scope chain of the dynamic Execution Code, that is, the location where the eval function is executed, and the scope chain of the execution environment.

5. the variables declared in the dynamic Execution Code can be deleted using the delete operator.

Lack of standards: ES3 does not explicitly describe its internal arguments and arguments. callee and arguments. callee. who should caller be. the implementation of various engines varies greatly. for example, the implementation of V8 is amazing (not the point, pass .).

 

Then let's take a look at es5:

Es5 is amazing. Based on ES3, Eval is not like people, but not ghosts. It has both built-in function features and keyword features. why? Es5 introduces a concept called direct call.

For the concept of direct call, please slam the link: In-depth analysis, what is direct call of eval.

 

Below are some simple demos:

 
; (Function () {var A = 1; var fn = eval; EVAL ('typeof A'); // number (eval) ('typeof '); // number (1, Eval) ('typeof A'); // undefined FN ('typeof A'); // undefined }());

 

PS:
After reading the preceding content, the only thing that needs to be explained here is only (eval). Here, the grouping operator is eliminated when the syntax tree is generated. therefore, (eval) is also called directly. just like (obj. in FN (), this points to the same object as obj. and (1, obj. in FN), this is global or undefined (strict mode ).

So is the direct call really reasonable? I personally think this is an unreasonable design. A good design should be:
Eval ('code', scope); scope can be a Boolean value to specify whether or not it is global. The default value is false. That is, it is non-global and the same effect as direct call.
True is global. How can this tough design be used? Further, this design will make it possible for us to specify the eval scope in the future.
Of course, if the design is not good, it will become the second with... it's not what we want to care about now.

 

Effect of es5 strict mode on Eval:

Es5, after defining the wonderful Eval, came up with new tricks. Because es5 introduced the concept of strict mode, we have to mention the influence of strict mode on eval.

In strict mode, the variables in the eval code are initialized... they are no longer accessible externally, that is, the eval has an independent variable environment (refer to the variable object of ES3)

Es5 strict mode popular science links: http://www.cnblogs.com/_franky/articles/2184461.html

Reference code:

 
'Use strict '; EVAL ('var A = 1;'); typeof A; // undefined

PS: ES3, which is different from es5. As a result, different browsers have different versions. They are based on different ecmascript standard versions, which leads to various implementation differences. They are not covered in this article...

The above section is some definitions of eval and popular science in ecma262. Later, we will introduce some interesting things.

 

 

We have always heard a well-known word from the old saying: Eval is edevil. in this article, the only opinion I want to output is that this sentence must be used improperly. I only pointed out the possible side effects here. how to Use Eval is something that everyone thinks about. maybe I will mention some of my own trade-offs at the end.

 

Demo1:

 
<SCRIPT> // eval ('var A; '); </SCRIPT> <SCRIPT> var A = 1; delete a; alert (typeof A) </SCRIPT>

In this example, the comments out of the eval part and the uncommented result are different. This is obviously a side effect, and it is the delete a in the subsequent script block; there is no way to correct it before the operation.

The reason for this problem is as follows: in the initialization phase of the variable, the initialized variable has some features (ecmascript is used internally to describe the attribute status .), ES3 is called {dontdelete}, es5 is called [[resumable], and is used to describe whether it can be deleted. or whether the feature can be rewritten. as we know before, Eval declares variables internally. In ES3, the {dontdelete} feature is not available, or es5 is described as [[writable able] = true. the variable can be deleted by Delete. also, elasticsearch provides a rigorous description of the variable initialization process. that is. in case of a variable declaration, check whether the current variable object (es5, called an Environment Record) has an attribute of the same name. if yes, nothing will be done. therefore, the variables declared first have priority (function declarations and parameters are different from variable declarations and are not covered in this article ). the conclusion is that, in non-strict mode, the identifier declaration in eval. side effects.

 

 

Demo2: demo2 is illustrated in the previous figure. (Note that this example is only used to describe the V8 engine. Different engine implementations may vary .)

(1 ).

 

(2 ).

 

 

Obviously, the two figures fully demonstrate that eval has an impact on some V8 optimization strategies. of course, it can have a similar effect, not just eval. If we return a group of functions here, the variables referenced inside each other are different. it will also cause similar problems. that is, function a is referenced, and function B is not referenced. however, they will be flat and stored in the upper layer of the scope chain. here I have some differences with ash. He thinks V8 has done this for better GC. I think it is to reduce the flat processing scope chain and the extra memory usage. but we all use black box speculation. so it is for reference only.

 

 

Demo3:

Reference code:

 
VaR fn = function (x) {return x + X;} var test = function () {return function (x) {return FN (x );} // eval ('')} (); console. time ('test'); For (VAR I = 1000000; I --; test (1); console. timeend ('test'); // eval ('')

The two eval values commented out in demo3 have different influences on V8 performance. However, the eval in the inner layer has 20 times the influence on V8 performance.. Even if it appears after return, it will never be executed.

The data here is incorrect. Enabling the console seems to affect the running score. close the console panel. run the command directly and use alert to output the command. Although the eval still suffers performance loss, the impact is minimal. in the above example, there is no Eval, which actually only consumes Ms. not XXX times.

So a simple and crude way of V8 is. during lexical and syntax analysis, Eval is found and confirmed to be called directly by direct call. some optimization strategies will be eliminated to varying degrees... the optimization strategy here is similar to the prototype chain optimization method called fast property access. create a hidden class in the execution environment where "Hot code" is located. this is an inline binding concept. replace the identifier or attribute search in the original code with this binding relationship. obviously, this kind of optimization can greatly improve the performance in hot code in deep scope chains or deep object attribute searches. this mechanism is similar to the V8 engine mentioned above and implements a flat scope chain. but unfortunately. eval ('') destroys all this. the reason is that eval can insert additional items in the current scope, including functions, variables, and so on. because of eval participation, the actual identifier or expression will change the evaluate result. this results in incorrect inline binding.

 

Write it here. Don't go to bed again, and you won't be able to go to work tomorrow... you'll have time to fill in some demos, or fill in the missing stuff .....

Oh, yes. Let me express my views on eval. It should be used. If it is confirmed that there are no security problems and there is no performance bottleneck on the system. use it boldly .. because it is a good choice for some needs .... okay, you have time to complete this part ..... I can't help it anymore ....

 

In the end, I will post a post about more tests and results for the above questions for your reference only:

Http://www.otakustay.com/eval-performance-profile/

Http://www.otakustay.com/about-closure-and-gc/

 

 

 

 

 Add three things that have not been mentioned before:

1. eval ('xxx') itself.

In V8, the results of eval ('xxx') and function ('xxx') are cached. if the same content is executed multiple times, the performance issue is not that serious. some JS templates use similar cache compilation results. it is also out of similar considerations.

 

2. functions, and non-direct call Eval, do not have side effects in demo2, because their calling context is considered to be the same as eval in global code.

 

 

3. Balance.

I 'd like to write this point over and over again, my personal opinion. I think Eval is completely usable when necessary. for example, @ Lao Zhao's wind. JS scenarios. in fact, among the many domestic frameworks, Zhao's wind. JS is a favorite of mine. innovation, needs in specific scenarios. productivity. is his value. only when you are raped multiple times by asynchronous callbacks with various in-depth nesting. you will try to improve the development method. maybe you have tried various frameworks of promise pattern. but in my opinion, from the perspective of productivity, it cannot be comparable to that of windjs.

 

In addition, I have encountered a situation in my actual project. we have a specific serialization and deserialization data requirement. however, to verify the data at the same time, we integrate some token functions into the serialized deserialization rules. at this time, I specifically wrote a subset constraint of the JSON syntax (not a real subset, but an extra number of syntax restrictions added on the basis of a subset ). through clever design of rules and constraints. I cut down the situations that require syntax analysis to process. in this way, you only need to implement a state machine. only lexical analysis can complete deserialization and Token verification. I even violate some principles of the state machine design to improve performance. for example, set the nine states of undefined. put it in a State to avoid performance loss caused by State migration. therefore, my ll1 lexical analyzer is an opportunistic product that violates the design principles. however, it implements time complexity O (n) during deserialization, so it brings certain performance. however, this solution was eventually abandoned. instead, use regular expression verification + eval. the reason is that Eval is faster .. At this time, the performance problems are mainly focused on regular expressions (not discussed in this article). So the eval is slow. It depends on who is compared. Isn't it? And. 1. If deserialization data is repeated, it may also hit the cache in the advanced browser... of course, you do not need to rely on the scope chain. function for dynamic execution, which may be a better solution. but in some scenarios, you can't leave him alone. use it.

 

Finally, only you really think that the use of eval leads to memory overhead and performance loss which are unacceptable in some high-performance requirements. however, we cannot bear the productivity brought by windjs. @ Old Zhao, didn't he think of it long ago? That's the extra cost of pre-compilation... It's just a habit. After you automate all the work, it's okay.

 

 

 

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.