Skip to content

Commit 3b9fcd8

Browse files
soyainembeaudru
authored andcommitted
Chinese Transition Part-1 (mbeaudru#43)
* init chinese file * init translation of zh-CN * delete * init Simplified Chinese file * update translation * complete part-1 variable declaration * update TOC * update TOC
1 parent 65851e0 commit 3b9fcd8

File tree

1 file changed

+201
-1
lines changed

1 file changed

+201
-1
lines changed

translations/zh-CN.md

Lines changed: 201 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,204 @@
1313

1414
除此之外,我(作者:[Manuel Beaudru](https://github.com/mbeaudru))偶尔会写上一些我的小技巧,也会注意提示这只是我的个人提议。
1515

16-
> **注:** 这篇文档里提到的大多数概念来自于目前最新的 JavaScript(ES2015,即 ES6),你可以在[这里]http://es6-features.org)新增的特性,网站做得很棒。
16+
> **注:** 这篇文档里提到的大多数概念来自于目前最新的 JavaScript(ES2015,即 ES6),你可以在[这里](http://es6-features.org)查看新增的特性,网站做得很棒。
17+
18+
### 参考材料
19+
20+
当你觉得有的概念不容易理解时,你可以在下面的链接里面寻找答案。
21+
22+
- [MDN (Mozilla Developer Network)](https://developer.mozilla.org/zh-CN/search?q=)
23+
- [You don't know JS(书)](https://github.com/getify/You-Dont-Know-JS)
24+
- [ES6 新特性和例子](http://es6-features.org)
25+
- [WesBos 博客中 ES6 类别](http://wesbos.com/category/es6/)
26+
- [Reddit (JavaScript)](https://www.reddit.com/r/javascript/)
27+
- [Google](https://www.google.com/) 可直接查找特定的博客和资源
28+
- [StackOverflow](https://stackoverflow.com/questions/tagged/javascript)
29+
30+
## 目录
31+
32+
- [Modern JavaScript Cheatsheet 简体中文版](#Modern-JavaScript-Cheatsheet-简体中文版)
33+
* [简介](#简介)
34+
+ [初心](#初心)
35+
+ [参考材料](#参考材料)
36+
* [目录](#目录)
37+
* [正文](#正文)
38+
+ [变量声明: var, const, let](#变量声明-var-const-let)
39+
- [简述](#简述)
40+
- [代码示例](#代码示例)
41+
- [详述](#详述)
42+
- [延伸资料](#延伸资料)
43+
+ [箭头函数](#箭头函数)
44+
- [简述](#简述)
45+
- [详述](#详述)
46+
* [简洁性](#简洁性)
47+
* [*this* 关键字](#this-关键字)
48+
- [延伸资料](#延伸资料)
49+
50+
## 正文
51+
52+
### 变量声明: var, const, let
53+
54+
在 JavaScript 中,声明变量时可以用三个不同的关键词,分别是 `var``let` 以及 `const` ,它们各有异同。
55+
56+
#### 简述
57+
58+
`const` 声明的变量,不能被重新赋值,而另两个 `var``let` 是可以的。
59+
60+
所以我建议默认情况下你都用 `const` 来声明变量,在你需要 *改变* 或是声明之后再重新指派它的时候,才用 `let` 来声明变量。
61+
62+
63+
| - | 作用域 | 是否可重新赋值 | 是否可变 | [暂存死区](#tdz_sample) |
64+
| ----- | ---- | ------- | -------------------------- | ------------------- |
65+
| const | 块级 | × | [](#const_mutable_sample) ||
66+
| let | 块级 ||||
67+
| var | 函数 ||| × |
68+
69+
#### 代码示例
70+
71+
```javascript
72+
const person = "Nick";
73+
person = "John" // 因为 person 不能被重新赋值,所以会报错
74+
```
75+
76+
```javascript
77+
let person = "Nick";
78+
person = "John";
79+
console.log(person) // "John", 使用 let 声明的变量可以重新赋值
80+
```
81+
82+
#### 详述
83+
84+
简单来讲,变量的作用域([*scope*](#scope_def))是指“在这部分代码中可以访问到此变量”。
85+
86+
##### var
87+
88+
使用 `var` 定义的变量,其作用域是定义它的函数内部(*function scoped*),也就是说在函数内部创建一个 `var` 变量的时候,在此函数内部可以任意访问这个变量,但在函数之外,这样的局部变量是无法被访问的。
89+
90+
我建议你这样理解,如果一个变量是 *X 作用域(scoped)* 类型的,那就是说这个变量是 X 的属性之一。(译注:X 有 function 和 block 两类,代表函数作用域和块级作用域。)
91+
92+
```javascript
93+
function myFunction() {
94+
var myVar = "Nick";
95+
console.log(myVar); // "Nick" - 在这个函数中 myVar 可被访问到
96+
}
97+
console.log(myVar); // 抛出错误 ReferenceError, 在函数之外 myVar 则无法访问
98+
```
99+
100+
继续来看变量的作用域,下面有更多精妙的例子:
101+
102+
```javascript
103+
function myFunction() {
104+
var myVar = "Nick";
105+
if (true) {
106+
var myVar = "John";
107+
console.log(myVar); // "John"
108+
// 实际上 myVar 是函数级作用域变量,重新声明的时候,相当于用 "John" 抹去了 myVar 之前的值 "Nick"
109+
}
110+
console.log(myVar); // "John" - 可见 if 块中的代码会如何影响变量
111+
}
112+
console.log(myVar); // 抛出错误 ReferenceError, 在函数之外 myVar 则无法访问
113+
```
114+
115+
另外,*var* 声明的变量在执行的时候,就像会被移动到作用域的开始,这就是我们所说的[变量声明提升(var hoisting)](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/**var)
116+
117+
所以看下面这段代码:
118+
119+
```javascript
120+
console.log(myVar) // undefined -- 没有提示错误
121+
var myVar = 2;
122+
```
123+
124+
之所以没有发生错误,是因为它执行时会被解释为这样:
125+
126+
```javascript
127+
var myVar;
128+
console.log(myVar) // undefined -- 没有提示错误
129+
myVar = 2;
130+
```
131+
132+
##### let
133+
134+
`var``let` 几乎是一样的,但是用 `let` 声明的变量有如下特性:
135+
136+
- *块级作用域*( block scoped )
137+
- 在被赋值之前,是**无法**访问使用的
138+
- 在同一个作用域之下,不能被重新声明
139+
140+
我们来看看之前例子中提到的块级作用域( block scoping )的效果:
141+
142+
```javascript
143+
function myFunction() {
144+
let myVar = "Nick";
145+
if (true) {
146+
let myVar = "John";
147+
console.log(myVar); // "John"
148+
// 实际上 myVar 是块级作用域的变量,在 if 块中,我们相当于是创建了一个新变量,
149+
// 这个变量在此块之外是无法被访问的,而且它完全区别于我们创建的第一个 myVar 变量!
150+
}
151+
console.log(myVar); // "Nick", 可见 if 块中的代码,并没有影响到这个变量的值
152+
}
153+
console.log(myVar); // 抛出错误 ReferenceError,在函数外部无法访问到 myVar。
154+
```
155+
156+
<a name="tdz_sample"></a>现在,来看看 *let*(和 *const* )声明的变量在赋值前无法访问是什么意思:
157+
158+
```javascript
159+
console.log(myVar) // 提示错误 ReferenceError !
160+
let myVar = 2;
161+
```
162+
163+
这就是它们和 *var* 变量的区别,如果你在还未赋值给 *let* 或者 *const* 变量之前,就想读写它,是会提示错误的。这种情况常被称作暂存死区([*Temporal dead zone*](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/let#let_的暂存死区与错误))或者 *TDZ*
164+
165+
> **注意:** 从技术上讲,*let**const* 变量声明时也存在提升,但并不代表它们的赋值也会被提升。但由于它被设计成了赋值之前无法使用,所以我们直观感觉上它没有被提升,但其实是存在提升的。如果想了解更多细节,请看[这篇文章](http://jsrocks.org/2015/01/temporal-dead-zone-tdz-demystified)
166+
167+
168+
另外,在同一作用域内你不能重新声明一个 *let* 变量。
169+
170+
```js
171+
let myVar = 2;
172+
let myVar = 3; // 提示语法错误 SyntaxError
173+
```
174+
175+
##### const
176+
177+
`const` 声明的变量很像 `let`,但它不能被重新赋值。
178+
179+
总结一下 `const` 变量的特点如下:
180+
181+
- *块级作用域*
182+
- 赋值之前无法使用
183+
- 在同一个作用域内部,你不能重新声明一个变量
184+
- 不能被重新指派
185+
186+
```Javascript
187+
const myVar = "Nick";
188+
myVar = "John" // 提示错误,不允许重新赋值 const 变量
189+
```
190+
191+
<a name="const_mutable_sample"></a>但这里有一个小细节:`const` 变量并非完全[不可变](#mutation_def),如果这个变量是 `object``array` 类型的值,那它的值是**可以改变**的。assign
192+
193+
对于对象类型来说:
194+
195+
```js
196+
const person = {
197+
name: 'Nick'
198+
};
199+
person.name = 'John' // 这会生效的!person 并非完全重新指派( reassigned ),只是值变化了( mutated )
200+
console.log(person.name) // "John"
201+
person = "Sandra" // 提示错误,因为用 const 声明的变量不能被重新指派
202+
```
203+
204+
对于数组类型来说:
205+
206+
```js
207+
const person = [];
208+
person.push('John'); // 这也会生效!person 并非完全重新指派( reassigned ),只是值变化了( mutated )
209+
console.log(person[0]) // "John"
210+
person = ["Nick"] // 提示错误,因为用 const 声明的变量不能被重新指派
211+
```
212+
213+
#### 延伸资料
214+
215+
- [How let and const are scoped in JavaScript - WesBos](http://wesbos.com/javascript-scoping/)
216+
- [Temporal Dead Zone (TDZ) Demystified](http://jsrocks.org/2015/01/temporal-dead-zone-tdz-demystified)

0 commit comments

Comments
 (0)