Skip to content

Commit 613c64d

Browse files
committed
Add eval, undefined, null, semicolon, setTimeout, setInterval section
1 parent 2143895 commit 613c64d

File tree

4 files changed

+168
-180
lines changed

4 files changed

+168
-180
lines changed

doc/zh/core/eval.md

+39-19
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
## Why not to use `eval`
1+
## 为什么不要使用 `eval`
22

3-
The `eval` function will execute a string of JavaScript code in the local scope.
3+
`eval` 函数会在当前作用域中执行一段 JavaScript 代码字符串。
44

55
var foo = 1;
66
function test() {
@@ -11,8 +11,7 @@ The `eval` function will execute a string of JavaScript code in the local scope.
1111
test(); // 3
1212
foo; // 1
1313

14-
But `eval` only executes in local scope when it is being called **directly** *and*
15-
the name of the called function is actually `eval`.
14+
但是 `eval` 只在被**直接**调用并且调用函数就是 `eval` 本身时,才在当前作用域中执行。
1615

1716
var foo = 1;
1817
function test() {
@@ -24,25 +23,46 @@ the name of the called function is actually `eval`.
2423
test(); // 2
2524
foo; // 3
2625

27-
The use of `eval` should be avoided at **all costs**. 99.9% of its "uses" can be
28-
achieved **without** it.
26+
[译者注][30]:上面的代码等价于在全局作用域中调用 `eval`,和下面两种写法效果一样:
27+
28+
// 写法一:直接调用全局作用域下的 foo 变量
29+
var foo = 1;
30+
function test() {
31+
var foo = 2;
32+
window.foo = 3;
33+
return foo;
34+
}
35+
test(); // 2
36+
foo; // 3
37+
38+
// 写法二:使用 call 函数修改 `eval` 执行的上下文为全局作用域
39+
var foo = 1;
40+
function test() {
41+
var foo = 2;
42+
eval.call(window, 'foo = 3');
43+
return foo;
44+
}
45+
test(); // 2
46+
foo; // 3
47+
48+
**任何情况下**我们都应该避免使用 `eval` 函数。99.9% 使用 `eval` 的场景都有**不使用** `eval` 的解决方案。
2949

30-
### `eval` in disguise
50+
### 伪装的 `eval``eval` in disguise)
51+
52+
[定时函数](#other.timeouts) `setTimeout``setInterval` 都可以接受字符串作为它们的第一个参数。
53+
这个字符串**总是**在全局作用域中执行,因此 `eval` 在这种情况下没有被直接调用。
54+
3155

32-
The [timeout functions](#other.timeouts) `setTimeout` and `setInterval` can both
33-
take a string as their first argument. This string will **always** get executed
34-
in the global scope since `eval` is not being called directly in that case.
56+
### 安全问题(Security issues)
3557

36-
### Security issues
58+
`eval` 也存在安全问题,因为它会执行**任意**传给它的代码,
59+
在代码字符串未知或者是来自一个不信任的源时,绝对不要使用 `eval` 函数。
3760

38-
`eval` also is a security problem as it executes **any** code given to it,
39-
it should **never** be used with strings of unknown or untrusted origins.
61+
### 结论(In conclusion)
4062

41-
### In conclusion
63+
绝对不要使用 `eval`,任何使用它的代码都会在它的工作方式,性能和安全性方面受到质疑。
64+
如果一些情况必须使用到 `eval` 才能正常工作,首先它的设计会受到质疑,这**不应该**是首选的解决方案,
65+
一个更好的不使用 `eval` 的解决方案应该得到充分考虑并优先采用。
4266

43-
`eval` should never be used, any code that makes use of it is to be questioned in
44-
its workings, performance and security. In case something requires `eval` in
45-
order to work, its design is to be questioned and should **not** be used in the
46-
first place, a *better design* should be used, that does not require the use of
47-
`eval`.
4867

68+
[30]: http://cnblogs.com/sanshi/

doc/zh/core/semicolon.md

+35-40
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,27 @@
1-
## Automatic semicolon insertion
1+
## 自动分号插入
22

3-
Although JavaScript has C style syntax, it does **not** enforce the use of
4-
semicolons in the source code, it is possible to omit them.
3+
尽管 JavaScript 有 C 的代码风格,但是它****强制要求在代码中使用分号,实际上可以省略它们。
54

6-
But JavaScript is not a semicolon-less language, it in fact needs the
7-
semicolons in order to understand the source code. Therefore the JavaScript
8-
parser **automatically** inserts them whenever it encounters a parse
9-
error due to a missing semicolon.
5+
JavaScript 不是一个没有分号的语言,恰恰相反上它需要分号来就解析源代码。
6+
因此 JavaScript 解析器在遇到由于缺少分号导致的解析错误时,会**自动**在源代码中插入分号。
107

118
var foo = function() {
12-
} // parse error, semicolon expected
9+
} // 解析错误,分号丢失
1310
test()
1411

15-
Insertion happens, and the parser tries again.
12+
自动插入分号,解析器重新解析。
1613

1714
var foo = function() {
18-
}; // no error, parser continues
15+
}; // 没有错误,解析继续
1916
test()
2017

21-
The automatic insertion of semicolon is considered to be one of **biggest**
22-
design flaws in the language, as it *can* change the behavior of code.
18+
自动的分号插入被认为是 JavaScript 语言**最大**的设计缺陷之一,因为它**改变代码的行为。
2319

24-
### How it works
2520

26-
The code below has no semicolons in it, so it is up to the parser to decide where
27-
to insert them.
21+
### 工作原理(How it works)
22+
23+
下面的代码没有分号,因此解析器需要自己判断需要在哪些地方插入分号。
24+
2825

2926
(function(window, undefined) {
3027
function test(options) {
@@ -53,62 +50,60 @@ to insert them.
5350

5451
})(window)
5552

56-
Below is the result of the parser's "guessing" game.
53+
下面是解析器"猜测"的结果。
5754

5855
(function(window, undefined) {
5956
function test(options) {
6057

6158
// Not inserted, lines got merged
6259
log('testing!')(options.list || []).forEach(function(i) {
6360

64-
}); // <- inserted
61+
}); // <- 插入分号
6562

6663
options.value.test(
6764
'long string to pass here',
6865
'and another long string to pass'
69-
); // <- inserted
66+
); // <- 插入分号
7067

71-
return; // <- inserted, breaks the return statement
72-
{ // treated as a block
68+
return; // <- 插入分号, 改变了 return 表达式的行为
69+
{ // 作为一个代码段处理
7370

7471
// a label and a single expression statement
7572
foo: function() {}
76-
}; // <- inserted
73+
}; // <- 插入分号
7774
}
78-
window.test = test; // <- inserted
75+
window.test = test; // <- 插入分号
7976

8077
// The lines got merged again
8178
})(window)(function(window) {
82-
window.someLibrary = {}; // <- inserted
79+
window.someLibrary = {}; // <- 插入分号
80+
81+
})(window); //<- 插入分号
8382

84-
})(window); //<- inserted
83+
> **注意:** JavaScript 不能正确的处理 return 表达式紧跟换行符的情况,
84+
> 虽然这不能算是自动分号插入的错误,但这确实是一种不希望的副作用。
8585
86-
> **Note:** The JavaScript parser does not "correctly" handle return statements
87-
> which are followed by a new line, while this is not neccessarily the fault of
88-
> the automatic semicolon insertion, it can still be an unwanted side-effect.
8986

90-
The parser drastically changed the behavior of the code above, in certain cases
91-
it does the **wrong thing**.
87+
解析器显著改变了上面代码的行为,在另外一些情况下也会做出**错误的处理**
9288

93-
### Leading parenthesis
9489

95-
In case of a leading parenthesis, the parser will **not** insert a semicolon.
90+
### 前置括号(Leading parenthesis)
91+
92+
在前置括号的情况下,解析器**不会**自动插入分号。
9693

9794
log('testing!')
9895
(options.list || []).forEach(function(i) {})
9996

100-
This code gets transformed into one line.
97+
上面代码被解析器转换为一行。
10198

10299
log('testing!')(options.list || []).forEach(function(i) {})
103100

104-
Chances are **very** high that `log` does **not** return a function; therefore,
105-
the above will yield a `TypeError` stating that `undefined is not a function`.
101+
`log` 函数的执行结果**极大**可能**不是**函数;这种情况下就会出现 `TypeError` 的错误,详细错误信息可能是 `undefined is not a function`
102+
106103

107-
### In conclusion
104+
### 结论(In conclusion
108105

109-
It is highly recommended to **never** omit semicolons, it is also advocated to
110-
keep braces on the same line with their corresponding statements and to never omit
111-
them for one single-line `if` / `else` statements. Both of these measures will
112-
not only improve the consistency of the code, they will also prevent the
113-
JavaScript parser from changing its behavior.
106+
建议**绝对**不要省略分号,同时也提倡将花括号和相应的表达式放在一行,
107+
对于只有一行代码的 `if` 或者 `else` 表达式,也不应该省略花括号。
108+
这些良好的编程习惯不仅可以提到代码的一致性,而且可以防止解析器改变代码行为的错误处理。
114109

doc/zh/core/undefined.md

+33-42
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,45 @@
1-
## `undefined` and `null`
1+
## `undefined` `null`
22

3-
JavaScript has two distinct values for `nothing`, the more useful of these two
4-
being `undefined`.
3+
JavaScript 有两个表示 `` 的值,其中比较有用的是 `undefined`
54

6-
### The value `undefined`
75

8-
`undefined` is a type with exactly one value: `undefined`.
6+
### `undefined`的值(The value `undefined`
97

10-
The language also defines a global variable that has the value of `undefined`,
11-
this variable is also called `undefined`. But this variable is **not** a constant,
12-
nor is it a keyword of the language. This means that its *value* can be easily
13-
overwritten.
8+
`undefined` 是一个值为 `undefined` 的类型。
149

15-
> **ES5 Note:** `undefined` in ECMAScript 5 is **no longer** *writable* in strict
16-
> mode, but its name can still be shadowed by for example a function with the name
17-
> `undefined`.
10+
这个语言也定义了一个全局变量,它的值是 `undefined`,这个变量也被称为 `undefined`
11+
但是这个变量**不是**一个常量,也不是一个关键字。这意味着它的**可以轻易被覆盖。
1812

19-
Some examples for when the value `undefined` is returned:
13+
> **ES5 提示:** 在 ECMAScript 5 的严格模式下,`undefined` **不再是** *可写*的了。
14+
> 但是它的名称仍然可以被隐藏,比如定义一个函数名为 `undefined`
2015
21-
- Accessing the (unmodified) global variable `undefined`.
22-
- Implicit returns of functions due to missing `return` statements.
23-
- `return` statements which do not explicitly return anything.
24-
- Lookups of non-existent properties.
25-
- Function parameters which do not had any explicit value passed.
26-
- Anything that has been set to the value of `undefined`.
16+
下面的情况会返回 `undefined` 值:
2717

28-
### Handling changes to the value of `undefined`
18+
- 访问未修改的全局变量 `undefined`
19+
- 由于没有定义 `return` 表达式的函数隐式返回。
20+
- `return` 表达式没有显式的返回任何内容。
21+
- 访问不存在的属性。
22+
- 函数参数没有被显式的传递值。
23+
- 任何被设置为 `undefined` 值的变量。
24+
2925

30-
Since the global variable `undefined` only holds a copy of the actual *value* of
31-
`undefined`, assigning a new value to it does **not** change the value of the
32-
*type* `undefined`.
26+
### 处理 `undefined` 值的改变(Handling changes to the value of `undefined`
3327

34-
Still, in order to compare something against the value of `undefined` it is
35-
necessary to retrieve the value of `undefined` first.
28+
由于全局变量 `undefined` 只是保存了 `undefined` 类型实际**的副本,
29+
因此对它赋新值**不会**改变类型 `undefined` 的值。
3630

37-
In order to protect code against a possible overwritten `undefined` variable, a
38-
common technique used is to add an additional parameter to an
39-
[anonymous wrapper](#function.scopes), that gets no argument passed to it.
31+
然而,为了方便其它变量和 `undefined` 做比较,我们需要事先获取类型 `undefined` 的值。
32+
33+
为了避免可能对 `undefined` 值的改变,一个常用的技巧是使用一个传递到[匿名包装器](#function.scopes)的额外参数。
34+
在调用时,这个参数不会获取任何值。
4035

4136
var undefined = 123;
4237
(function(something, foo, undefined) {
43-
// undefined in the local scope does
44-
// now again refer to the value
38+
// 局部作用域里的 undefined 变量重新获得了 `undefined` 值
4539

4640
})('Hello World', 42);
4741

48-
Another way to achieve the same effect would be to use a declaration inside the
49-
wrapper.
42+
另外一种达到相同目的方法是在函数内使用变量声明。
5043

5144
var undefined = 123;
5245
(function(something, foo) {
@@ -55,18 +48,16 @@ wrapper.
5548

5649
})('Hello World', 42);
5750

58-
The only difference being here, that this version results in 4 more bytes being
59-
used in case it is minified and there is no other `var` statement inside the
60-
anonymous wrapper.
51+
这里唯一的区别是,在压缩后并且函数内没有其它需要使用 `var` 声明变量的情况下,这个版本的代码会多出 4 个字节的代码。
52+
53+
[译者注][30]:这里有点绕口,其实很简单。
54+
如果此函数内没有其它需要声明的变量,那么 `var ` 总共 4 个字符(包含一个空白字符)就是专门为 undefined 变量准备的,相比上个例子多出了 4 个字节。
6155

62-
### Uses of `null`
6356

64-
While `undefined` in the context of the JavaScript language is mostly used in
65-
the sense of a traditional *null*, the actual `null` (both a literal and a type)
66-
is more or less just another data type.
57+
### 使用 `null`(Uses of `null`
6758

68-
It is used in some JavaScript internals (like declaring the end of the
69-
prototype chain by setting `Foo.prototype = null`), but in almost all cases it
70-
can be replaced by `undefined`.
59+
JavaScript 中的 `undefined` 的使用场景类似于其它语言中的 *null*,实际上 JavaScript 中的 `null` 是另外一种数据类型。
7160

61+
它在 JavaScript 内部有一些使用场景(比如声明原型链的终结 `Foo.prototype = null`),但是大多数情况下都可以使用 `undefined` 来代替。
7262

63+
[30]: http://cnblogs.com/sanshi/

0 commit comments

Comments
 (0)