DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> JavaScript入門知識 >> 關於JavaScript >> JS實例教程:當心JavaScript代碼陷阱
JS實例教程:當心JavaScript代碼陷阱
編輯:關於JavaScript     

網頁制作poluoluo文章簡介:可能被你忽略的 JavaScript 代碼陷阱.

下面這段代碼,你知道有哪些錯誤嗎:

var g_bar = "bar";
function foo(container, config) {
var container = container || document,
name = config.name || "無名氏",
isLive = config.isLive || true;
var g_bar = g_bar || "";
if(g_foo) {
/* your code */
}
}
foo(document, {isLive: false});

請仔細思考後再往下閱讀。

—- 幫助你思考的刷屏線 開始 —-

—- 幫助你思考的刷屏線 結束 —-

1. isLive = config.isLive || true, 當傳入的值有可能就是0, undefined, null, false, "", NaN這六個 falsy 值時,用 || 來設定默認值不妥當。更保險的做法是:

isLive = "isLive" in config ? config.isLive : true;

如果是獨立變量,可以采用:

someVar = typeof someVar !== "undefined" ? someVar : defaultValue;

注意:大部分情況下,用 || 已經夠用,比如:

container = container || document
name = config.name || "無名氏"

一切皆權衡。

2. var g_bar = g_bar || "", 原意是取全局變量 g_bar 的值給內部變量 g_bar, 默認為空字符串。然而,實際情況等價為:

var g_bar;
g_bar = g_bar || "";

很明顯,|| 號左邊的 g_bar 也是內部變量,並且為 undefined, 因此var g_bar = g_bar || ""實際上是var g_bar = "", 沒有滿足代碼的原始意圖。

思考:代碼中的var container = container || document有無問題?為什麼?

3. if(g_foo) { /* code */ }, 這段代碼在執行時會報錯。我們都知道在 JS 裡,變量不定義就可以用。但一定要清楚,未定義的變量,僅僅是可寫,但不可讀。比如:

g_foo = 2; // 等價 window.g_foo = 2
var t = g_foo2; // 不等價為 var t = window.g_foo2, 會報錯

具體原因可以參見 JavaScript 運行機制淺探:

未定義變量意味著在 scriptObject 的變量表中找不到,JS 引擎會沿著 scriptObject 的 upvalue 往上尋找,如果都沒找到,對於寫操作 i = 1; 最後就會等價為 window.i = 1; 給 window 對象新增了一個屬性。對於讀操作,如果一直追溯到全局執行環境的 scriptObject 上都找不到,就會產生運行期錯誤。

因此嚴謹的寫法是:

if(window.g_foo) {
/* your code */
}

不要小看這些細微之處,有時會讓人抓狂的。但這些細微之處又很容易被忽略或濫用。比如 YUI 2.8r4 裡,有一個遺傳了很久的 bug:

var NOTHING = [];
// ....
later: function(when, o, fn, data, periodic) {
when = when || 0;
o = o || {};
var m = fn, d = data, f, r;
// ...
if (d && !L.isArray(d)) {
d = [data];
}
f = function() {
m.apply(o, d || NOTHING);
};
// ...
}

當你的調用代碼類似Lang.later(delay[0], o, "show", index)時,如果 index 不幸是 base-0 的,那麼取 0 時,m.apply(o, d || NOTHING)會讓你得到“驚喜”。更妥的做法是類似 YUI3 中的修正:

// ...
if (!L.isArray(d)) {
d = [data];
}?
f = function() {
m.apply(o, d);
};
//...

對於 || 和 && 的用法,很多 JS 書籍(無論中外),都用來片面強調 JS 的靈活性,包括 Douglas 的《JavaScript The Good Parts》中也存在誤導。

最後,有感於 NCZ 今天寫的 Writing Maintainable Code, 再舉一例(和本文主題關系不明顯,但的確又有關系,交給你去思考啰):

var isBoy = true;
isBoy = typeof isGirl !== "undefined" ? !isGirl : true;

或者來個耍酷的代碼:

var isBoy = true;
(typeof isGirl !== "undefined") && (isBoy =  !isGirl);

然而,以上兩種寫法,無論從代碼長度還是性能上講,都不如更直白的寫法:

var isBoy = true;
if(typeof isGirl !== "undefined") isBoy =  !isGirl;

簡單質樸,往往是最好的。

XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved