A few days ago, when it comes to JS, try not to use eval, but what exactly is eval? Today we're going to talk about the eval thing.
First look at this definition:
Definitions and usage
The eval () function computes a string and executes the JavaScript code in it.
Grammar
Eval (String)
Parameters
Describe
String required. The string to evaluate, which contains the JAVASCRIPT expression to evaluate or the statement to execute.
return value
The value, if any, obtained by calculating the string.
Description
The method accepts only the original string as a parameter, and if the string argument is not the original string, the method returns without any changes. Therefore, do not pass a String object as an argument for the eval () function.
If you attempt to overwrite the Eval attribute or assign the eval () method to another property and call it through this property, the ECMAScript implementation allows a Evalerror exception to be thrown.
Thrown
Throws an SyntaxError exception if there are no valid expressions and statements in the argument.
If Eval () is invoked illegally, a Evalerror exception is thrown.
If the Javascript code passed to eval () generates an exception, eval () passes the exception to the caller.
Tips and comments
Tip: Although the eval () is very powerful, it is not much used in practice.
Instance code:
The Eval function receives an argument s, and if S is not a string, it returns directly to S. Otherwise execute the S statement. If the S statement executes the result is a value, this value is returned, otherwise the undefined is returned.
A special note is that the object declaration syntax "{}" does not return a value, which needs to be enclosed in parentheses to return the value, as the simple example reads:
The code is as follows |
Copy Code |
var code1= ' "A" + 2 '; An expression
Varcode2= ' {a:2} '; Statement
Alert (eval (code1)); -> ' A2 '
Alert (eval (code2)); ->undefined
Alert (eval (' + Code2 + ')); ->[object Object]
|
The feature of the Eval function, which is always executed within the context variable space (also known as: Package, closure) that calls it, whether it is a variable definition or a function definition.
eval Scope
Let's look at this piece of code:
The code is as follows |
Copy Code |
var x = 1; (function () { Eval (' var x = 123; '); })(); Console.log (x);
|
This code gets 1 instead of 123.
If the code you want to execute for eval is global, there are several ways.
The code is as follows |
Copy Code |
var x = 1; (function () { Window.eval (' var x = 123; '); })(); Console.log (x);
|
This method standard browser can get 123 while ie6-8 is still 1
The same for example
The code is as follows |
Copy Code |
var arr = [0,0,0,0,0,0]; (function () { var arr = [1,1,1,1,1,1]; var _eval = eval; Window.eval (' arr[0] = 123; '); Eval.call (null, ' arr[1] = 123; '); _eval (' arr[2] = 123; '); (0,eval) (' arr[3] = 123; '); })(); Console.log (arr); |
0,1 seemingly does not support ie8-2,3 seemingly does not support ie7-
Anyway, in the final analysis, compatibility is problematic.
But there's a execscript in IE that works very well.
The code is as follows |
Copy Code |
var x = 1; (function () { (!-[1,]? execscript:eval) (' var x = 123; '); })(); Console.log (x); |
Eval can not be implemented in the global space, which brings a lot of problems to development, but also see a lot of people depressed.
But now I finally found a solution, hey, can be compatible with IE and Firefox, the following methods:
The code is as follows |
Copy Code |
var x2={}//my namespace:)
X2. Eval=function (code) {
if (!! (window.attachevent &&!window.opera)) {
Ie
Execscript (code);
}else{
Not IE
Window.eval (code);
}
}
|
Now, if you want to define global code within a function, you can call the X2.eval_r (code) method.
The code is as follows |
Copy Code |
var s= ' global ';
function Demo3 () {
X2. Eval (' var s= ' local ');
}
Demo3 ();
alert (s); -> ' Local ' |
Eval parsing json
The code is as follows:
code is as follows |
copy code |
var data=" { Root: [ {name: ' 1 ', Value: ' 0 '}, {name: ' 6101 ', Value: ' Beijing '}, {name: ' 6102 ', Value: ' Tianjin '}, {name: ' 6103 ', Value: ' Shanghai City '}, {name: ' 6104 ', Value: ' Chongqing '}, {name: ' 6105 ', Value: ' Weinan '}, {name: ' 6106 ', Value: ' Yanan '}, {name: ' 6107 ', Value: ' Hanzhong '}, {name: ' 6108 ', Value: ' Yulin '}, {name: ' 6109 ', Value: ' Ankang '}, {name: ' 6110 ', Value: ' Shangluo '} ] } '; |
This is the result processing method obtained in two ways, based on the data type--json object and string that jquery asynchronously obtains.
1. For the JSON string returned by the server, if the jquery asynchronous request is not typed or accepted as a string, it is necessary to do an object-by-case, either in a cumbersome way, or to put the string in eval () once. This is also a good way to get JSON objects in a normal javascipt way:
var dataobj=eval ("(+data+)");//Convert to JSON object
Why do you want to eval here to add "(" ("+data+") ");/"?
The reason is that the eval itself is a problem. Since JSON starts and ends with "{}", in JS it is treated as a block of statements, so it must be coerced into an expression. The purpose of the
Plus parenthesis is to force the Eval function to force an expression in parentheses (expression) into an object when processing JavaScript code instead of executing as a statement (statement). For example, an object literal {}, if the outer bracket is not added, Eval recognizes the curly braces as the opening and closing tags of the JavaScript code block, then {} will be considered to have executed an empty statement. So the following two execution results are different:
code is as follows:
The code is as follows |
Copy Code |
Alert (eval ("{}");//return undefined Alert (eval ({}));/return Object[object]
|
For this type of writing, in JS, you can see everywhere.
such as: (function ()) {} (); When doing closure operation.
The code is as follows:
The code is as follows |
Copy Code |
Alert (dataObj.root.length)//output The number of child objects of root $.each (Dataobj.root,fucntion (Idx,item) { if (idx==0) { return true; } Output the name and value of each root child object Alert ("Name: +item.name+", Value: "+item.value"); })
|
Note: For the general JS generation JSON object, only need to replace the $.each () method with the For statement, the other unchanged.
2. For the JSON string returned by the server, the eval () method is not required if the jquery asynchronous request sets the type (typically this configuration property) to "JSON" or uses the $.getjson () method to get the server back. Because the result is already a JSON object, just call the object directly, and here take the $.getjson method as an example to illustrate the data processing method:
The code is as follows:
The code is as follows |
Copy Code |
$.getjson ("http://www.111cn.net/", {param: "Gaoyusi"},function (data) { The data returned here is already a JSON object The following other actions are the same as the first case $.each (Data.root,function (Idx,item) { if (idx==0) { Return true;//with Countinue, returns false with break } Alert ("Name: +item.name+", Value: "+item.value"); }); }); |
In particular, it is important to note that the eval () method in mode 1 executes the string (possibly the JS script) dynamically, which can easily cause a system security problem. So you can use a few Third-party client script libraries that circumvent eval (), such as JSON in JavaScript, which provides a script library of no more than 3k.
Common errors performed by *eval
---source
The code is as follows |
Copy Code |
Console.log ("Eval Usage"); var Str1_err = "function () {Console.log (' Run Fun1 ')};"; try{ eval (str1_err); }catch (e) { Console.log ("error! Eval (Str1_err) "); Console.log (E.tostring ()); } var str1 = "function fun1 () {console.log (' Run Fun1 ')}; FUN1 (); "; eval (str1); var str2_err = "{name: ' Dzh '}"; var result; try{ result = eval (str2_err); Console.log (Result.tostring ()); Console.log ("Name:" + result.name); }catch (e) { Console.log ("error! Eval (Str2_err) "); Console.log (E.tostring ()); } STR2 = "({name: ' Dzh '})"; result = eval (str2); Console.log (Result.tostring ()); Console.log ("Name:" + result.name); ---results Eval Usage error! Eval (Str1_err) Syntaxerror:unexpected Token ( Run FUN1 Dzh name:undefined [Object Object] Name:dzh |
---Analysis of the reasons
1) Str1_err describes the error caused by the definition of anonymous function; Encountered empty ' () ', will be an error;
2) Str2_err explained that for ' {} ', the engine parsing will be interpreted as a block of code, and the program is intended to be a direct amount of objects; So the usual way is to add parentheses around the ' {} ' perimeter, so Eval performs the evaluation first, and it returns the object.
Review, when using eval, consider how the engine understands the incoming string code.