Luar's Flash Playground:delete和undefined/null的分別
新聞(100)
觀點或評論(93)
Flash書(63)
教程(65)
Design Patterns(3)
FlashCom筆記(45)
Flash Remoting筆記(27)
Flex筆記(11)
Flash Lite筆記(14)
PHP資訊(22)
Ajax筆記(9)
習作(46)
組件(15)
酷站(31)
學習資源(28)
書籍推介(15)
本站與我(90)
RSS瀏覽器
聯絡
熱愛鑽研
Ajax
ActionScript
Flash
Flash Lite
Flex
Flash Remoting
FlashCom
Director
Lingo
PHP
Multiplayer Game

搜尋
VCASMO
delete和undefined/null的分別 (25-04-2005)

對於Variable/Object或者Event Handler的刪除,很多人會用delete,或者將他們設定為undefined/null,表面看來沒有分別。我一直都是用delete,而且覺得設定為undefined/null不是Best Practice,看到別人的Code用這方法,特別不舒服,於是抽空做了一些試驗,看看三者究竟有沒有分別。

1. 對於Variable/Object:undefined和null可以是有分別,也可以是沒有分別

//var a;
b = null;
var c = 10;
delete c;
if (a == null) {
  trace("a is null");
}
if (a == undefined) {
  trace("a is undefined");
}
if (b == null) {
  trace("b is null");
}

if (b == undefined) {
  trace("b is undefined");
}
if (c == null) {
  trace("c is null");
}
if (c == undefined) {
  trace("c is undefined");
}

if (a == null and a == undefined) {
  trace("typeof a "+typeof a);
}
if (b == undefined and b == null) {
  trace("typeof b "+typeof b);
}
if (c == undefined and c == null) {
  trace("typeof c "+typeof c);
}
所有結果都是true,trace會輸出,undefined和null是沒有分別的。

但打開Debug Panel,只有b剩下:
null_debugpanel.jpg

如果將==改為!=,例如:

//var a;
b = null;
var c = 10;
delete c;
if (a != null) {
  trace("a is null");
}
if (a != undefined) {
  trace("a is undefined");
}
if (b != null) {
  trace("b is null");
}
if (b != undefined) {
  trace("b is undefined");
}
if (c != null) {
  trace("c is null");
}
if (c != undefined) {
  trace("c is undefined");
}
結果都是false,沒有trace會輸出,undefined和null是沒有分別的。

如果將==(equality)換成===(strict equality)後,輸出結果只剩下:

a is undefined
b is null
c is undefined
在嚴格Data Typing下,undefined和null是有分別的。(程式碼粗體的三句)

[下載範例]


2. 對於MovieClip Mouse相關Event Handler:delete和undefined/null是有分別

假設有兩個MovieClip(mc1,mc2)有以下程式碼:

mc1.onRelease = function() {
  trace(this);
  delete this.onRelease;
};
mc2.onRelease = function() {
  trace(this);
  this.onRelease = null;
  //this.onRelease = undefined;
};
當Mouse clicked,移走再移入mc1,Cursor已經由手指變回箭頭,但對於mc2,無論設定為undefined/null,移走再移入,Cursor仍然是手指,當然再Mouse clicked都不會有trace輸出。

[下載範例]


3. 對於原型鏈(Prototype Chain),delete和undefined/null是有分別

MovieClip.prototype.x = 10;

myMC.x = 20;
myMC.x = undefined;
trace(myMC.x); // undefined

myMC.x = 20;
delete myMC.x;
trace(myMC.x); // 10
對於不存在Property,Flash會沿Prototype Chain向上找(Resolve),因此決定不要一個Property時,想清楚是否需要向上引用,正確決定用delete或undefined。


4. 對於MovieClip.onEnterFrame:結果沒有分別,速度上有分別

刪除MovieClip.onEnterFrame,常見的做法有兩種:

delete this.onEnterFrame;
this.onEnterFrame = undefined;
這種做法在Flashcoder Mailing List過去是熱門討論的題目,delete被認為是Best Practice,首先,delete的東西,當然佔用較少Memory。在刪除onEnterFrame做法上,Get/Set設定速度是比delete object快,但是從MovieClip的EventHandler執行效率來說,Delete了,onEnterFrame是不存在,但設定為undefined,onEnterFrame這Handler是存在,變相浪費CPU繼續檢查onEnterFrame事件有什麼Function連繫著可以執行。另一方面,由於Prototype Chain原因,有人則會認為設定onEnterFrame為null有較佳效率,避免Flash每次都向上找。


5. ActionScript 2對非動態產生的onEnterFrame事件無法delete刪除

下載這範例執行,ball1.fla的關聯Class如下:

class ball1 extends MovieClip {
  function onEnterFrame() {
    _x += 20;
    if (_x>550) {
      delete this.onEnterFrame;
    }
  }
}
用delete是無法刪除onEnterFrame,MovieClip是不會停下,一直走出畫面,如果設定為undefined/null則可以使MovieClip停下。

對於動態產生的onEnterFrame事件,如ball2.fla的關聯Class:

class ball2 extends MovieClip {
  function ball2() {
    this.onEnterFrame = moving;
  }
  function moving() {
    _x += 20;
    if (_x>550) {
      delete this.onEnterFrame;
      //this.onEnterFrame = undefined;
    }
  }
}
無論是用delete或設定為undefined/null都可以使MovieClip停下。


其他參考資料

本文章由luar發表。
意見
  • 哗.呢篇文章好正呀.
    学到好多野.
    以后真的是要正确决定使用delete与undefined/null了.
    受益唔少!!

    e路信峰於25-04-2005發表

  • 我正可以用这个!3Q!

    KELU於25-04-2005發表

  • 我更习惯与用undefined
    因为flash所以属性在初始化以前都是undefined的(而非null)

    以前经常用del,但是发现有时候会不管用,也没仔细研究,就统一用undefined了

    由goldgoat於26-04-2005發表

  • Flash沒有清楚分開undefined和undeclared才給你這樣錯覺吧

    luar於26-04-2005發表

同組文章

Movable Type 3.15系統支持,Luar's Production版權所有。