1010 console.log(i); // 10
1111 }
1212
13- > ** Note:** When not used in an assignment, return statement or as a function
14- > argument, the ` {...} ` notation will get interpreted as a block statement and
15- > ** not** as an object literal. This, in conjunction with
16- > [ automatic insertion of semicolons] ( #core.semicolon ) , can lead to subtle errors.
13+ > ** 注意:** 如果不是在賦值語句中,而是在 return 表達式或者函數參數中, ` {...} ` 將會作為程式碼中的解析,而不是作為物件的字面語法解析。
14+ > 如果考慮到 [ 自動分號插入] ( #core.semicolon ) ,可能會造成一些不易察覺的錯誤。
1715
16+ JavaScript 中沒有寫示的命名空間定義,這代表著它所有定義的東西都是 * 全域共享* 在同一個命名空間下。
1817
19- There are also no distinct namespaces in JavaScript, which means that everything
20- gets defined in one * globally shared* namespace.
21-
22- Each time a variable is referenced, JavaScript will traverse upwards through all
23- the scopes until it finds it. In the case that it reaches the global scope and
24- still has not found the requested name, it will raise a ` ReferenceError ` .
18+ 每次引用一個變數,JavaScript 會向上找整個作用域直到找到這個變數為止。
19+ 如果在全域中無法找到那個變數,它會拋出 ` ReferenceError ` 錯誤碼。
2520
2621### 全域變數的壞處
2722
@@ -31,17 +26,14 @@ still has not found the requested name, it will raise a `ReferenceError`.
3126 // script B
3227 var foo = '42'
3328
34- The above two scripts do ** not** have the same effect. Script A defines a
35- variable called ` foo ` in the * global* scope, and script B defines a ` foo ` in the
36- * current* scope.
29+ 上面兩個腳本 * 不會* 有同樣的效果。腳本 A 在 * 全域* 空間定義了變數 ` foo ` ,腳本 B 定義了 ` foo ` 在目前的區間內。
3730
38- Again, that is ** not** at all the * same effect* : not using ` var ` can have major
39- implications.
31+ 再次強調,上面的效果是 ** 完全不同** ,不使用 ` var ` 會導致隱性的全域變數。
4032
41- // global scope
33+ // 全域作用區
4234 var foo = 42;
4335 function test() {
44- // local scope
36+ // 局部作用區
4537 foo = 21;
4638 }
4739 test();
@@ -51,52 +43,51 @@ Leaving out the `var` statement inside the function `test` will override the
5143value of ` foo ` . While this might not seem like a big deal at first, having
5244thousands of lines of JavaScript and not using ` var ` will introduce horrible,
5345hard-to-track-down bugs.
46+ 在函數 ` test ` 中部使用 ` var ` 會覆蓋到原本在外面的 ` foo ` 。
47+ 雖然看起來不是什麼大問題,但是當程式有幾千行的時候沒有使用 ` var ` 會照成難以追蹤的臭蟲。
48+
5449
55- // global scope
50+ // 全域作用域
5651 var items = [/* some list */];
5752 for(var i = 0; i < 10; i++) {
5853 subLoop();
5954 }
6055
6156 function subLoop() {
62- // scope of subLoop
63- for(i = 0; i < 10; i++) { // missing var statement
64- // do amazing stuff!
57+ // subLoop 的作用域
58+ for(i = 0; i < 10; i++) { // 缺少了 var
59+ // 做一些事情
6560 }
6661 }
6762
68- The outer loop will terminate after the first call to ` subLoop ` , since ` subLoop `
69- overwrites the global value of ` i ` . Using a ` var ` for the second ` for ` loop would
70- have easily avoided this error. The ` var ` statement should ** never** be left out
71- unless the * desired effect* is to affect the outer scope.
63+ 在外面的迴圈在呼叫第一次 ` subLoop ` 之後就會停止,因為 ` subLoop ` 全域變數中的 ` i ` 被覆蓋了。
64+ 在第二次使用 ` for ` 迴圈的時候,使用 ` var ` 就可以避免這種錯誤。
65+ 在宣告變數的時候 ** 絕對不要** 忘記 ` var ` ,除非就是 ` 希望他的效果 ` 是取改變外部的作用域。
7266
73- ### Local Variables
67+ ### 局部變數
7468
75- The only source for local variables in JavaScript are
76- [ function] ( #function.general ) parameters and variables declared via the
77- ` var ` statement.
69+ 在 javascript 中能用兩種方式來宣告局部變數。
70+ [ 函式] ( #function.general ) 參數和透過 ` var ` 來宣告變數。
7871
79- // global scope
72+ // 全域變數
8073 var foo = 1;
8174 var bar = 2;
8275 var i = 2;
8376
8477 function test(i) {
85- // local scope of the function test
78+ // 函式 test 內部的局部作用域
8679 i = 5;
8780
8881 var foo = 3;
8982 bar = 4;
9083 }
9184 test(10);
9285
93- While ` foo ` and ` i ` are local variables inside the scope of the function ` test ` ,
94- the assignment of ` bar ` will override the global variable with the same name.
86+ ` foo ` 和 ` i ` 是它的局部變數在 ` test ` 函式中,但是在 ` bar ` 的賦值會覆蓋全區域的作用域內的同名變數。
9587
96- ### Hoisting
88+ ### 變數宣告
9789
98- JavaScript ** hoists** declarations. This means that both ` var ` statements and
99- ` function ` declarations will be moved to the top of their enclosing scope.
90+ JavaScript 會 ** 提昇** 變數宣告, 這代表著 ` var ` 和 ` function ` 的圈告都會被提升到當前作用域的頂端。
10091
10192 bar();
10293 var bar = function() {};
@@ -115,16 +106,14 @@ JavaScript **hoists** declarations. This means that both `var` statements and
115106 }
116107 }
117108
118- The above code gets transformed before execution starts. JavaScript moves
119- the ` var ` statements, as well as ` function ` declarations, to the top of the
120- nearest surrounding scope.
109+ 在上面的程式碼會被轉化在執行之前。 JavaScript 會把 ` var ` ,和 ` function ` 宣告,放到最頂端最接近的作用區間
121110
122- // var statements got moved here
123- var bar, someValue; // default to 'undefined'
111+ // var 被移到這裡
112+ var bar, someValue; // 值等於 'undefined'
124113
125- // the function declaration got moved up too
114+ // function 的宣告也被搬上來
126115 function test(data) {
127- var goo, i, e; // missing block scope moves these here
116+ var goo, i, e; // 沒有作用域的也被搬至頂端
128117 if (false) {
129118 goo = 1;
130119
@@ -136,98 +125,79 @@ nearest surrounding scope.
136125 }
137126 }
138127
139- bar(); // fails with a TypeError since bar is still 'undefined'
140- someValue = 42; // assignments are not affected by hoisting
128+ bar(); // 出錯: TypeError , bar 還是 'undefined'
129+ someValue = 42; // 賦值語句不會被提昇規則影響
141130 bar = function() {};
142131
143132 test();
144133
145- Missing block scoping will not only move ` var ` statements out of loops and
146- their bodies, it will also make the results of certain ` if ` constructs
147- non-intuitive.
134+ 沒有作用域區間不只會把 ` var ` 放到迴圈之外,還會使得 ` if ` 表達式更難看懂。
148135
149- In the original code, although the ` if ` statement seemed to modify the * global
150- variable* ` goo ` , it actually modifies the * local variable* - after hoisting
151- has been applied.
136+ 在一般的程式中,雖然 ` if ` 表達式中看起來修改了 * 全域變數* ` goo ` ,但實際上在提昇規則被運用後,卻是在修改 * 局部變數*
152137
153- Without knowledge of * hoisting* , one might suspect the code below would raise a
154- ` ReferenceError ` .
138+ 如果沒有提昇規則的話,可能會出現像下面的看起來會出現 ` ReferenceError ` 的錯誤。
155139
156- // check whether SomeImportantThing has been initialized
140+ // 檢查 SomeImportantThing 是否已經被初始化
157141 if (!SomeImportantThing) {
158142 var SomeImportantThing = {};
159143 }
160144
161- But of course, this works due to the fact that the ` var ` statement is being
162- moved to the top of the * global scope* .
145+ 但是它沒有錯誤,因為 ` var ` 的表達式會被提升到 * 全域作用域* 的頂端。
163146
164147 var SomeImportantThing;
165148
166- // other code might initialize SomeImportantThing here, or not
149+ // 有些程式,可能會初始化。
150+ SomeImportantThing here, or not
167151
168- // make sure it's there
152+ // 檢查是否已經被初始化。
169153 if (!SomeImportantThing) {
170154 SomeImportantThing = {};
171155 }
172156
173- ### Name Resolution Order
174-
175- All scopes in JavaScript, including the * global scope* , have the special name
176- [ ` this ` ] ( #function.this ) , defined in them, which refers to the * current object* .
157+ ### 名稱解析順序
158+
159+ JavaScript 中所有的作用區,包括 * 全域作用域* ,都有一個特殊的名字 [ ` this ` ] ( #function.this ) , 在它們裡面被定義,指向當前的物件
177160
178- Function scopes also have the name [ ` arguments ` ] ( #function.arguments ) , defined in
179- them, which contains the arguments that were passed to the function.
161+ 函式作用域也有一個名稱叫做 [ ` arguments ` ] ( #function.arguments ) , 定義它們,其中包括傳到函式內的參數。
180162
181- For example, when trying to access a variable named ` foo ` inside the scope of a
182- function, JavaScript will look up the name in the following order:
163+ 例如,它們開始試著進入到 ` foo ` 的作用域裡面, JavaScript 會依照下面的順序去查詢:
183164
184- 1 . In case there is a ` var foo ` statement in the current scope, use that.
185- 2 . If one of the function parameters is named ` foo ` , use that.
186- 3 . If the function itself is called ` foo ` , use that.
187- 4 . Go to the next outer scope, and start with ** # 1 ** again.
165+ 1 . 當作用域內是否有 ` var foo ` 的定義。
166+ 2 . 函式形式參數是否有使用 ` foo ` 名稱定義。
167+ 3 . 函式自身是剖叫做 ` foo ` 。
168+ 4 . 回溯到上一個層級然後再從第一個開始往下去查。
188169
189- > ** Note:** Having a parameter called ` arguments ` will ** prevent** the creation
190- > of the default ` arguments ` object.
170+ > ** 注意: ** 自定義 ` arguments ` 參數會阻止原生的 ` arguments ` 的物件創立
191171
192- ### Namespaces
172+ ### 命名空間
193173
194- A common problem associated with having only one global namespace is the
195- likelihood of running into problems where variable names clash. In JavaScript,
196- this problem can easily be avoided with the help of * anonymous wrappers* .
174+ 只有一個全域作用域會導致常見的錯誤是命名衝突。在 JavaScript 中可以透過 * 匿名包裝器* 來解決。
197175
198176 (function() {
199- // a self contained "namespace"
177+ // 自己本身的匿名空間
200178
201179 window.foo = function() {
202- // an exposed closure
180+ // 對外公開的函式
203181 };
204182
205- })(); // execute the function immediately
183+ })(); // 馬上執行這個匿名函式
206184
185+ 匿名函式被認為是 [ 表達式] ( #function.general ) 因此為了要可以調用,它們會先被執行。
207186
208- Unnamed functions are considered [ expressions] ( #function.general ) ; so in order to
209- being callable, they must first be evaluated.
210-
211- ( // evaluate the function inside the parentheses
187+ ( // 小括號內的先被執行
212188 function() {}
213- ) // and return the function object
214- () // call the result of the evaluation
189+ ) // 回傳函數對象
190+ () // 調用上面的執行結果
215191
216- There are other ways to evaluate and directly call the function expression
217- which, while different in syntax, behave the same way.
192+ 還有其他方式也可以像上面一樣調用函式的方式達到
218193
219- // A few other styles for directly invoking the
220194 !function(){}()
221195 +function(){}()
222196 (function(){}());
223197 // and so on...
224198
225199### 結語
226200
227- It is recommended to always use an * anonymous wrapper* to encapsulate code in
228- its own namespace. This does not only protect code against name clashes, but it
229- also allows for better modularization of programs.
230-
231- Additionally, the use of global variables is considered ** bad practice** . ** Any**
232- use of them indicates badly written code that is prone to errors and hard to maintain.
201+ 建議最好是都用 * 匿名包裝器* 來封裝你的程式碼在自己的命名區間內。這不僅是要防止命名衝突也可以使得程序更有模組化。
233202
203+ 另外,全域變數是個 ** 不好的** 習慣,因為它會帶來錯誤和更難去維護。
0 commit comments