可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Many programmers say it is a bad practice to use the eval()
function:
When is JavaScript's eval() not evil?
I'd like to take a moment to address the premise of your question - that eval() is "evil"...
Is this eval() dangerous?
Buggy evaled code can violate security properties just as easily as buggy source code...
Why not eval() JSON?
There are a number of ways that your security may be compromised...
Is there ever a good reason to use eval()?
Yes - when there is no other way to accomplish the given task with a reasonable level of clarity... This eliminates 99% of cases where eval is used...
Why is eval unsafe in javascript?
The danger of eval only rears its ugly head when you are serving a script written by alice to user bob for bob's browser to eval...
So why does it exist in the first place?
回答1:
Because sometimes there is a need. All the same reasons for/against using eval
in JavaScript can likely be shared with the use of reflection in Java, for example.
However, I agree with everything you quoted in your question. Many reasons for using it are ill-advised, and best done differently - but sometimes, there is still a need, or it is simply the "best choice" over other available alternatives. (I'd focus on the answers to Is there ever a good reason to use eval()? for additional reasons.)
+1 to your question for good research.
回答2:
eval()
exists because sometimes you want to give complete programmatic control of your application to code passed in at run time.
Languages without an eval()
feature can definitely provide (a subset? all?) of this functionality by asking each programmer to essentially write their own eval()
-- lex the input, parse the input, create new objects as necessary, run methods or functions on them via simple string comparisons or similar. In essence, duplicate the entire interpreter that already exists and is debugged and fast.
回答3:
Eval is actually a powerful feature and there are some things that are impossible to do without it. For example:
- Evaluate code received from a remote server. (Say you want to make a site that can be remotely controlled by sending JavaScript code to it?)
- Evaluate user-written code. Without eval, you can't program, for example, an online editor/REPL.
- Creating functions of arbitrary length dynamically (function.length is readonly, so the only way is using eval).
- Loading a script and returning it's value. If your script is, for example, a self-calling function, and you want to evaluate it and get it's result (eg:
my_result = get_script_result("foo.js")
), the only way of programming the function get_script_result is by using eval inside it.
- Re-creating a function in a different closure.
And anything else you'd want to do that involves creating code on the fly.
The reason it is considered "evil" is because it's classicaly used by novices to do things that the language can handle natively. For example, the code below:
age_of_erick = 34;
age_of_john = 21;
person = "erick";
eval("console.log('age_of_"+person+"')");
And the code below:
age = {erick:34, john:21};
person = "erick";
console.log(age["erick"]);
Both do the same thing, except one parses a string, generates code from it, compiles into machine code and then runs, while the other reads a value from a hash, which is a lot faster.
回答4:
There's a research publication exacty on this topic:
The Eval
That Men Do -- A Large-scale Study of the Use of Eval
in JavaScript Applications
Mirror on Wayback Machine
It is to me the most comprehensive answer to this question to date.
Quote from the abstract:
We have recorded the behavior of 337 MB of strings given as
arguments to 550,358 calls to the eval function exercised in over
10,000 web sites.
Amongst other, they identified 9 categories of recurring eval
:
- JSON - A JSON string or variant.
- JSONP - A padded JSON string.
- Library -One or more function definitions.
- Read - Read access to an
object’s property.
- Assign - Assignment to a local variable or
object property.
- Typeof - Type test expression.
- Try - Trivial
try/catch block.
- Call - Simple function/method call.
- Empty -
Empty or blank string.
A snippet from the conclusion (which is too long to be quoted entierly):
[...] While many uses eval
were legitimate, many were unnecessary and
could be replaced with equivalent and safer code. We started this work
with the hope that it would show that eval
can be replaced by other
features. Unfortunately our data does not support this conclusion.[...]
A paper well worth reading.
回答5:
The eval()
feature is like scissors. You're an adult, it's your responsibility to not run with them.
I've seen the design philosophy of dynamic languages (like JavaScript) summarised as preferring to enable smart people to do clever things above trying to prevent stupid people from doing silly things. (Unfortunately I can't recall the original source or phrasing.)
If you're worried about introducing bugs with eval, you can use strict mode. It seems to prevent some of the problems with how the feature is designed. (That is, as a "magic" function allowed to clobber your namespace.)
回答6:
Eval exists to simplify tasks in JavaScript. You can use it evaluate multiple statements. Instead of having to find another way you can use eval to do such things. Even though it is discouraged it has considerable power and use.