總是將代碼包裹成一個 IIFE(Immediately-Invoked Function Expression),用以創(chuàng)建獨立隔絕的定義域。這一舉措可防止全局命名空間被污染。
IIFE 還可確保你的代碼不會輕易被其它全局命名空間里的代碼所修改(i.e. 第三方庫,window 引用,被覆蓋的未定義的關(guān)鍵字等等)。
不推薦
- var x = 10,
- y = 100;
- // Declaring variables in the global scope is resulting in global scope pollution. All variables declared like this
- // will be stored in the window object. This is very unclean and needs to be avoided.
- console.log(window.x + ' ' + window.y);
推薦
- // We declare a IIFE and pass parameters into the function that we will use from the global space
- (function(log, w, undefined){
- 'use strict';
- var x = 10,
- y = 100;
- // Will output 'true true'
- log((w.x === undefined) + ' ' + (w.y === undefined));
- }(window.console.log, window));
無論何時,想要創(chuàng)建一個新的封閉的定義域,那就用 IIFE。它不僅避免了干擾,也使得內(nèi)存在執(zhí)行完后立即釋放。
所有腳本文件建議都從 IIFE 開始。
立即執(zhí)行的函數(shù)表達式的執(zhí)行括號應(yīng)該寫在外包括號內(nèi)。雖然寫在內(nèi)還是寫在外都是有效的,但寫在內(nèi)使得整個表達式看起來更像一個整體,因此推薦這么做。
不推薦
- (function(){})();
推薦
- (function(){}());
so,用下列寫法來格式化你的 IIFE 代碼:
- (function(){
- 'use strict';
- // Code goes here
- }());
如果你想引用全局變量或者是外層 IIFE 的變量,可以通過下列方式傳參:
- (function($, w, d){
- 'use strict';
- $(function() {
- w.alert(d.querySelectorAll('div').length);
- });
- }(jQuery, window, document));
ECMAScript 5 嚴格模式可在整個腳本或獨個方法內(nèi)被激活。它對應(yīng)不同的 javascript 語境會做更加嚴格的錯誤檢查。嚴格模式也確保了 javascript 代碼更加的健壯,運行的也更加快速。
嚴格模式會阻止使用在未來很可能被引入的預(yù)留關(guān)鍵字。
你應(yīng)該在你的腳本中啟用嚴格模式,最好是在獨立的 IIFE 中應(yīng)用它。避免在你的腳本第一行使用它而導致你的所有腳本都啟動了嚴格模式,這有可能會引發(fā)一些第三方類庫的問題。
不推薦
- // Script starts here
- 'use strict';
- (function(){
- // Your code starts here
- }());
推薦
- (function(){
- 'use strict';
- // Your code starts here
- }());
總是使用 var
來聲明變量。如不指定 var,變量將被隱式地聲明為全局變量,這將對變量難以控制。如果沒有聲明,變量處于什么定義域就變得不清(可以是在 Document 或 Window 中,也可以很容易地進入本地定義域)。所以,請總是使用 var 來聲明變量。
采用嚴格模式帶來的好處是,當你手誤輸入錯誤的變量名時,它可以通過報錯信息來幫助你定位錯誤出處。
不推薦
- x = 10;
- y = 100;
推薦
- var x = 10,
- y = 100;
在 JavaScript 中變量和方法定義會自動提升到執(zhí)行之前。JavaScript 只有 function 級的定義域,而無其他很多編程語言中的塊定義域,所以使得你在某一 function 內(nèi)的某語句和循環(huán)體中定義了一個變量,此變量可作用于整個 function 內(nèi),而不僅僅是在此語句或循環(huán)體中,因為它們的聲明被 JavaScript 自動提升了。
我們通過例子來看清楚這到底是怎么一回事:
原 function
- (function(log){
- 'use strict';
- var a = 10;
- for(var i = 0; i < a; i++) {
- var b = i * i;
- log(b);
- }
- if(a === 10) {
- var f = function() {
- log(a);
- };
- f();
- }
- function x() {
- log('Mr. X!');
- }
- x();
- }(window.console.log));
被 JS 提升過后
- (function(log){
- 'use strict';
- // All variables used in the closure will be hoisted to the top of the function
- var a,
- i,
- b,
- f;
- // All functions in the closure will be hoisted to the top
- function x() {
- log('Mr. X!');
- }
- a = 10;
- for(i = 0; i < a; i++) {
- b = i * i;
- log(b);
- }
- if(a === 10) {
- // Function assignments will only result in hoisted variables but the function body will not be hoisted
- // Only by using a real function declaration the whole function will be hoisted with its body
- f = function() {
- log(a);
- };
- f();
- }
- x();
- }(window.console.log));
根據(jù)以上提升過程,你是否可理解以下代碼?
有效代碼
- (function(log){
- 'use strict';
- var a = 10;
- i = 5;
- x();
- for(var i; i < a; i++) {
- log(b);
- var b = i * i;
- }
- if(a === 10) {
- f = function() {
- log(a);
- };
- f();
- var f;
- }
- function x() {
- log('Mr. X!');
- }
- }(window.console.log));
正如你所看到的這段令人充滿困惑與誤解的代碼導致了出人意料的結(jié)果。只有良好的聲明習慣,也就是下一章節(jié)我們要提到的聲明規(guī)則,才能盡可能的避免這類錯誤風險。
提升聲明
為避免上一章節(jié)所述的變量和方法定義被自動提升造成誤解,把風險降到最低,我們應(yīng)該手動地顯示地去聲明變量與方法。也就是說,所有的變量以及方法,應(yīng)當定義在 function 內(nèi)的首行。
只用一個 var
關(guān)鍵字聲明,多個變量用逗號隔開。
不推薦
- (function(log){
- 'use strict';
- var a = 10;
- var b = 10;
- for(var i = 0; i < 10; i++) {
- var c = a * b * i;
- }
- function f() {
- }
- var d = 100;
- var x = function() {
- return d * d;
- };
- log(x());
- }(window.console.log));
推薦
- (function(log){
- 'use strict';
- var a = 10,
- b = 10,
- i,
- c,
- d,
- x;
- function f() {
- }
- for(i = 0; i < 10; i++) {
- c = a * b * i;
- }
- d = 100;
- x = function() {
- return d * d;
- };
- log(x());
- }(window.console.log));
把賦值盡量寫在變量申明中。
不推薦
- var a,
- b,
- c;
- a = 10;
- b = 10;
- c = 100;
推薦
- var a = 10,
- b = 10,
- c = 100;
總是使用 ===
精確的比較操作符,避免在判斷的過程中,由 JavaScript 的強制類型轉(zhuǎn)換所造成的困擾。
如果你使用 ===
操作符,那比較的雙方必須是同一類型為前提的條件下才會有效。
如果你想了解更多關(guān)于強制類型轉(zhuǎn)換的信息,你可以讀一讀 Dmitry Soshnikov 的這篇文章。
在只使用 ==
的情況下,JavaScript 所帶來的強制類型轉(zhuǎn)換使得判斷結(jié)果跟蹤變得復(fù)雜,下面的例子可以看出這樣的結(jié)果有多怪了:
- (function(log){
- 'use strict';
- log('0' == 0); // true
- log('' == false); // true
- log('1' == true); // true
- log(null == undefined); // true
- var x = {
- valueOf: function() {
- return 'X';
- }
- };
- log(x == 'X');
- }(window.console.log));
當我們在一個 if 條件語句中使用變量或表達式時,會做真假判斷。if(a == true)
是不同于 if(a)
的。后者的判斷比較特殊,我們稱其為真假判斷。這種判斷會通過特殊的操作將其轉(zhuǎn)換為 true 或 false,下列表達式統(tǒng)統(tǒng)返回 false:false
, 0
, undefined
, null
, NaN
, ''
(空字符串).
這種真假判斷在我們只求結(jié)果而不關(guān)心過程的情況下,非常的有幫助。
以下示例展示了真假判斷是如何工作的:
- (function(log){
- 'use strict';
- function logTruthyFalsy(expr) {
- if(expr) {
- log('truthy');
- } else {
- log('falsy');
- }
- }
- logTruthyFalsy(true); // truthy
- logTruthyFalsy(1); // truthy
- logTruthyFalsy({}); // truthy
- logTruthyFalsy([]); // truthy
- logTruthyFalsy('0'); // truthy
- logTruthyFalsy(false); // falsy
- logTruthyFalsy(0); // falsy
- logTruthyFalsy(undefined); // falsy
- logTruthyFalsy(null); // falsy
- logTruthyFalsy(NaN); // falsy
- logTruthyFalsy(''); // falsy
- }(window.console.log));
邏輯操作符 ||
和 &&
也可被用來返回布爾值。如果操作對象為非布爾對象,那每個表達式將會被自左向右地做真假判斷?;诖瞬僮鳎罱K總有一個表達式被返回回來。這在變量賦值時,是可以用來簡化你的代碼的。
不推薦
- if(!x) {
- if(!y) {
- x = 1;
- } else {
- x = y;
- }
- }
推薦
- x = x || y || 1;
這一小技巧經(jīng)常用來給方法設(shè)定默認的參數(shù)。
- (function(log){
- 'use strict';
- function multiply(a, b) {
- a = a || 1;
- b = b || 1;
- log('Result ' + a * b);
- }
- multiply(); // Result 1
- multiply(10); // Result 10
- multiply(3, NaN); // Result 3
- multiply(9, 5); // Result 45
- }(window.console.log));
總是使用分號,因為隱式的代碼嵌套會引發(fā)難以察覺的問題。當然我們更要從根本上來杜絕這些問題[1] 。以下幾個示例展示了缺少分號的危害:
- // 1.
- MyClass.prototype.myMethod = function() {
- return 42;
- } // No semicolon here.
- (function() {
- // Some initialization code wrapped in a function to create a scope for locals.
- })();
- var x = {
- 'i': 1,
- 'j': 2
- } // No semicolon here.
- // 2. Trying to do one thing on Internet Explorer and another on Firefox.
- // I know you'd never write code like this, but throw me a bone.
- [ffVersion, ieVersion][isIE]();
- var THINGS_TO_EAT = [apples, oysters, sprayOnCheese] // No semicolon here.
- // 3. conditional execution a la bash
- -1 == resultOfOperation() || die();
So what happens?
x[ffVersion, ieVersion][isIE]()
.die
總是被調(diào)用。因為數(shù)組減 1 的結(jié)果是 NaN
,它不等于任何東西(無論 resultOfOperation
是否返回 NaN
)。所以最終的結(jié)果是 die()
執(zhí)行完所獲得值將賦給 THINGS_TO_EAT
.Why?
JavaScript 中語句要以分號結(jié)束,否則它將會繼續(xù)執(zhí)行下去,不管換不換行。以上的每一個示例中,函數(shù)聲明或?qū)ο蠡驍?shù)組,都變成了在一句語句體內(nèi)。要知道閉合圓括號并不代表語句結(jié)束,JavaScript 不會終結(jié)語句,除非它的下一個 token 是一個中綴符[2] 或者是圓括號操作符。
這真是讓人大吃一驚,所以乖乖地給語句末加上分號吧。
澄清:分號與函數(shù)
分號需要用在表達式的結(jié)尾,而并非函數(shù)聲明的結(jié)尾。區(qū)分它們最好的例子是:
- var foo = function() {
- return true;
- }; // semicolon here.
- function foo() {
- return true;
- } // no semicolon here.
嵌套函數(shù)是非常有用的,比如用在持續(xù)創(chuàng)建和隱藏輔助函數(shù)的任務(wù)中。你可以非常自由隨意地使用它們。
切勿在語句塊內(nèi)聲明函數(shù),在 ECMAScript 5 的嚴格模式下,這是不合法的。函數(shù)聲明應(yīng)該在定義域的頂層。但在語句塊內(nèi)可將函數(shù)申明轉(zhuǎn)化為函數(shù)表達式賦值給變量。
不推薦
- if (x) {
- function foo() {}
- }
推薦
- if (x) {
- var foo = function() {};
- }
基本上你無法避免出現(xiàn)異常,特別是在做大型開發(fā)時(使用應(yīng)用開發(fā)框架等等)。
在沒有自定義異常的情況下,從有返回值的函數(shù)中返回錯誤信息一定非常的棘手,更別提多不優(yōu)雅了。不好的解決方案包括了傳第一個引用類型來接納錯誤信息,或總是返回一個對象列表,其中包含著可能的錯誤對象。以上方式基本上是比較簡陋的異常處理方式。適時可做自定義異常處理。
在復(fù)雜的環(huán)境中,你可以考慮拋出對象而不僅僅是字符串(默認的拋出值)。
- if(name === undefined) {
- throw {
- name: 'System Error',
- message: 'A name should always be specified!'
- }
- }
總是優(yōu)先考慮使用標準特性。為了最大限度地保證擴展性與兼容性,總是首選標準的特性,而不是非標準的特性(例如:首選 string.charAt(3)
而不是 string[3]
;首選 DOM 的操作方法來獲得元素引用,而不是某一應(yīng)用特定的快捷方法)。
如果你想在 JavaScript 中繼承你的對象,請遵循一個簡易的模式來創(chuàng)建此繼承。如果你預(yù)計你會遇上復(fù)雜對象的繼承,那可以考慮采用一個繼承庫,比如 Proto.js by Axel Rauschmayer.
簡易繼承請用以下方式:
- (function(log){
- 'use strict';
- // Constructor function
- function Apple(name) {
- this.name = name;
- }
- // Defining a method of apple
- Apple.prototype.eat = function() {
- log('Eating ' + this.name);
- };
- // Constructor function
- function GrannySmithApple() {
- // Invoking parent constructor
- Apple.prototype.constructor.call(this, 'Granny Smith');
- }
- // Set parent prototype while creating a copy with Object.create
- GrannySmithApple.prototype = Object.create(Apple.prototype);
- // Set constructor to the sub type, otherwise points to Apple
- GrannySmithApple.prototype.constructor = GrannySmithApple;
- // Calling a super method
- GrannySmithApple.prototype.eat = function() {
- // Be sure to apply it onto our current object with call(this)
- Apple.prototype.eat.call(this);
- log('Poor Grany Smith');
- };
- // Instantiation
- var apple = new Apple('Test Apple');
- var grannyApple = new GrannySmithApple();
- log(apple.name); // Test Apple
- log(grannyApple.name); // Granny Smith
- // Instance checks
- log(apple instanceof Apple); // true
- log(apple instanceof GrannySmithApple); // false
- log(grannyApple instanceof Apple); // true
- log(grannyApple instanceof GrannySmithApple); // true
- // Calling method that calls super method
- grannyApple.eat(); // Eating Granny Smith\nPoor Grany Smith
- }(window.console.log));
閉包的創(chuàng)建也許是 JS 最有用也是最易被忽略的能力了。關(guān)于閉包如何工作的合理解釋。
在簡單的循環(huán)語句中加入函數(shù)是非常容易形成閉包而帶來隱患的。下面的例子就是一個典型的陷阱:
不推薦
- (function(log, w){
- 'use strict';
- // numbers and i is defined in the current function closure
- var numbers = [1, 2, 3],
- i;
- for(i = 0; i < numbers.length; i++) {
- w.setTimeout(function() {
- // At the moment when this gets executed the i variable, coming from the outer function scope
- // is set to 3 and the current program is alerting the message 3 times
- // 'Index 3 with number undefined
- // If you understand closures in javascript you know how to deal with those cases
- // It's best to just avoid functions / new closures in loops as this prevents those issues
- w.alert('Index ' + i + ' with number ' + numbers[i]);
- }, 0);
- }
- }(window.console.log, window));
接下來的改進雖然已經(jīng)解決了上述例子中的問題或 bug,但還是違反了不在循環(huán)中創(chuàng)建函數(shù)或閉包的原則。
不推薦
- (function(log, w){
- 'use strict';
- // numbers and i is defined in the current function closure
- var numbers = [1, 2, 3],
- i;
- for(i = 0; i < numbers.length; i++) {
- // Creating a new closure scope with an IIFE solves the problem
- // The delayed function will use index and number which are
- // in their own closure scope (one closure per loop iteration).
- // ---
- // Still this is not recommended as we violate our rule to not
- // create functions within loops and we are creating two!
- (function(index, number){
- w.setTimeout(function() {
- // Will output as expected 0 > 1, 1 > 2, 2 > 3
- w.alert('Index ' + index + ' with number ' + number);
- }, 0);
- }(i, numbers[i]));
- }
- }(window.console.log, window));
接下來的改進已解決問題,而且也遵循了規(guī)范??墒?,你會發(fā)現(xiàn)看上去似乎過于復(fù)雜繁冗了,應(yīng)該會有更好的解決方案吧。
不完全推薦
- (function(log, w){
- 'use strict';
- // numbers and i is defined in the current function closure
- var numbers = [1, 2, 3],
- i;
- // Create a function outside of the loop that will accept arguments to create a
- // function closure scope. This function will return a function that executes in this
- // closure parent scope.
- function alertIndexWithNumber(index, number) {
- return function() {
- w.alert('Index ' + index + ' with number ' + number);
- };
- }
- // First parameter is a function call that returns a function.
- // ---
- // This solves our problem and we don't create a function inside our loop
- for(i = 0; i < numbers.length; i++) {
- w.setTimeout(alertIndexWithNumber(i, numbers[i]), 0);
- }
- }(window.console.log, window));
將循環(huán)語句轉(zhuǎn)換為函數(shù)執(zhí)行的方式問題能得到立馬解決,每一次循環(huán)都會對應(yīng)地創(chuàng)建一次閉包。函數(shù)式的風格更加值得推薦,而且看上去也更加地自然和可預(yù)料。
推薦
- (function(log, w){
- 'use strict';
- // numbers and i is defined in the current function closure
- var numbers = [1, 2, 3],
- i;
- numbers.forEach(function(number, index) {
- w.setTimeout(function() {
- w.alert('Index ' + index + ' with number ' + number);
- }, 0);
- });
- }(window.console.log, window));
eval()
不但混淆語境還很危險,總會有比這更好、更清晰、更安全的另一種方案來寫你的代碼,因此盡量不要使用 evil 函數(shù)。
只在對象構(gòu)造器、方法和在設(shè)定的閉包中使用 this
關(guān)鍵字。this 的語義在此有些誤導。它時而指向全局對象(大多數(shù)時),時而指向調(diào)用者的定義域(在 eval 中),時而指向 DOM 樹中的某一節(jié)點(當用事件處理綁定到 HTML 屬性上時),時而指向一個新創(chuàng)建的對象(在構(gòu)造器中),還時而指向其它的一些對象(如果函數(shù)被 call()
和 apply()
執(zhí)行和調(diào)用時)。
正因為它是如此容易地被搞錯,請限制它的使用場景:
函數(shù)式編程讓你可以簡化代碼并縮減維護成本,因為它容易復(fù)用,又適當?shù)亟怦詈透俚囊蕾嚒?/p>
接下來的例子中,在一組數(shù)字求和的同一問題上,比較了兩種解決方案。第一個例子是經(jīng)典的程序處理,而第二個例子則是采用了函數(shù)式編程和 ECMA Script 5.1 的數(shù)組方法。
例外:往往在重代碼性能輕代碼維護的情況之下,要選擇最優(yōu)性能的解決方案而非維護性高的方案(比如用簡單的循環(huán)語句代替 forEach)。
不推薦
- (function(log){
- 'use strict';
- var arr = [10, 3, 7, 9, 100, 20],
- sum = 0,
- i;
- for(i = 0; i < arr.length; i++) {
- sum += arr[i];
- }
- log('The sum of array ' + arr + ' is: ' + sum)
- }(window.console.log));
推薦
- (function(log){
- 'use strict';
- var arr = [10, 3, 7, 9, 100, 20];
- var sum = arr.reduce(function(prevValue, currentValue) {
- return prevValue + currentValue;
- }, 0);
- log('The sum of array ' + arr + ' is: ' + sum);
- }(window.console.log));
另一個例子通過某一規(guī)則對一個數(shù)組進行過濾匹配來創(chuàng)建一個新的數(shù)組。
不推薦
- (function(log){
- 'use strict';
- var numbers = [11, 3, 7, 9, 100, 20, 14, 10],
- numbersGreaterTen = [],
- i;
- for(i = 0; i < numbers.length; i++) {
- if(numbers[i] > 10) {
- numbersGreaterTen.push(numbers[i]);
- }
- }
- log('From the list of numbers ' + numbers + ' only ' + numbersGreaterTen + ' are greater than ten');
- }(window.console.log));
推薦
- (function(log){
- 'use strict';
- var numbers = [11, 3, 7, 9, 100, 20, 14, 10];
- var numbersGreaterTen = numbers.filter(function(element) {
- return element > 10;
- });
- log('From the list of numbers ' + numbers + ' only ' + numbersGreaterTen + ' are greater than ten');
- }(window.console.log));
建議使用 ECMA Script 5 中新增的語法糖和函數(shù)。這將簡化你的程序,并讓你的代碼更加靈活和可復(fù)用。
用 ECMA5 的迭代方法來迭代數(shù)組。使用 Array.forEach
或者如果你要在特殊場合下中斷迭代,那就用 Array.every
。
- (function(log){
- 'use strict';
- // Iterate over an array and break at a certain condition
- [1, 2, 3, 4, 5].every(function(element, index, arr) {
- log(element + ' at index ' + index + ' in array ' + arr);
- if(index !== 5) {
- return true;
- }
- });
- // Defining a simple javascript object
- var obj = {
- a: 'A',
- b: 'B',
- 'c-d-e': 'CDE'
- };
- // Iterating over the object keys
- Object.keys(obj).forEach(function(element, index, arr) {
- log('Key ' + element + ' has value ' + obj[element]);
- });
- }(window.console.log));
switch 在所有的編程語言中都是個非常錯誤的難以控制的語句,建議用 if else 來替換它。
用數(shù)組和對象字面量來代替數(shù)組和對象構(gòu)造器。數(shù)組構(gòu)造器很容易讓人在它的參數(shù)上犯錯。
不推薦
- // Length is 3.
- var a1 = new Array(x1, x2, x3);
- // Length is 2.
- var a2 = new Array(x1, x2);
- // If x1 is a number and it is a natural number the length will be x1.
- // If x1 is a number but not a natural number this will throw an exception.
- // Otherwise the array will have one element with x1 as its value.
- var a3 = new Array(x1);
- // Length is 0.
- var a4 = new Array();
正因如此,如果將代碼傳參從兩個變?yōu)橐粋€,那數(shù)組很有可能發(fā)生意料不到的長度變化。為避免此類怪異狀況,請總是采用更多可讀的數(shù)組字面量。
推薦
- var a = [x1, x2, x3];
- var a2 = [x1, x2];
- var a3 = [x1];
- var a4 = [];
對象構(gòu)造器不會有類似的問題,但是為了可讀性和統(tǒng)一性,我們應(yīng)該使用對象字面量。
不推薦
- var o = new Object();
- var o2 = new Object();
- o2.a = 0;
- o2.b = 1;
- o2.c = 2;
- o2['strange key'] = 3;
應(yīng)該寫成這樣:
推薦
- var o = {};
- var o2 = {
- a: 0,
- b: 1,
- c: 2,
- 'strange key': 3
- };
修改內(nèi)建的諸如 Object.prototype
和 Array.prototype
是被嚴厲禁止的。修改其它的內(nèi)建對象比如 Function.prototype
,雖危害沒那么大,但始終還是會導致在開發(fā)過程中難以 debug 的問題,應(yīng)當也要避免。
你可以通過自定義 toString()
來控制對象字符串化。這很好,但你必須保證你的方法總是成功并不會有其它副作用。如果你的方法達不到這樣的標準,那將會引發(fā)嚴重的問題。如果 toString()
調(diào)用了一個方法,這個方法做了一個斷言[3] ,當斷言失敗,它可能會輸出它所在對象的名稱,當然對象也需要調(diào)用 toString()
。
一般在語法和語義上真正需要時才謹慎地使用圓括號。不要用在一元操作符上,例如 delete
, typeof
和 void
,或在關(guān)鍵字之后,例如 return
, throw
, case
, new
等。
統(tǒng)一使用單引號(‘),不使用雙引號(“)。這在創(chuàng)建 HTML 字符串非常有好處:
- var msg = 'This is some HTML <div class="makes-sense"></div>';
用三元操作符分配或返回語句。在比較簡單的情況下使用,避免在復(fù)雜的情況下使用。沒人愿意用 10 行三元操作符把自己的腦子繞暈。
不推薦
- if(x === 10) {
- return 'valid';
- } else {
- return 'invalid';
- }
推薦
- return x === 10 ? 'valid' : 'invalid';
[1]:作者指的是采用嚴格規(guī)范的語句寫法,從根本上杜絕由分號缺失而引起的代碼歧義。
[2]:中綴符,指的是像 x + y
中的 +
。
[3]:斷言一般指程序員在測試測序時的假設(shè),一般是一些布爾表達式,當返回是 true 時,斷言為真,代碼運行會繼續(xù)進行;如果條件判斷為 false,代碼運行停止,你的應(yīng)用被終止。
更多建議: