2009-11-19 18 views
0

我有一個解引用JavaScript對象並將其設置爲NULL的問題。Javascript - 從外部數組中刪除對我的對象的引用

在這裏,我有一個文件夾實現,支持遞歸子目錄刪除。請參閱我的評論以瞭解我的困境。

function Folder(name, DOM_rows) { 
    this.name = name; 
    this.files = [].concat(DOM_rows); 
    this.subdirs = []; 
} 

Folder.prototype.AddDir(name, DOM_rows) { 
    this.subdirs.push(new Folder(name, DOM_rows)); 
} 

Folder.prototype.RemoveDir(folder) { 
    var stack = [folder]; 
    while(stack.length > 0) { 
     var cur = stack.pop(); 
     // do a post-order depth-first traversal, so dig to the deepest subdir: 
     if(cur.subdirs.length > 0) { 
      while(cur.subdirs.length > 0) { stack.push(cur.subdirs.pop()); } 
     } else { 
      // arrived at a leaf-level: 
      cur.files = null; 
      // now how do I delete cur from it's parent's subdirs array? 
      // the only way I know how is to keep a "cur.parentDir" reference, 
      // then find parent.subdirs[ index of cur ] and slice it out. 
      // How can I do the JS-equivalent of *cur = NULL? 
     } 
    } 
} 
+0

你沒有使用'RemoveDir'遞歸的原因?樣本中是否有任何附加處理在刪除時需要在文件或文件夾上執行? – outis 2009-11-20 00:33:00

+0

@outis:我只是喜歡迭代遞歸。在某些情況下遞歸執行它可能更具有空間效率,但是我知道寬度(每個級別的子級數)相對於深度而言會很小。實際上,我的應用程序不是關於文件夾和文件,而是具有相同的結構。我的「文件夾」對象有更多屬性需要處理和刪除。 – 2009-11-20 03:55:33

回答

4

注意你,你懷疑沒有大問題,因爲所有子目錄,但在folderRemoveDir將由stack.push(cur.subdirs.pop());

從他們的父母的subdir刪除,以找到一個子目錄家長,你可以利用的對象,如詞典,而不是subdirs的數組:給定一個文件夾

function Folder(name, DOM_rows, parent) { 
    this.name = name; 
    this.parent = parent; 
    this.files = [].concat(DOM_rows); 
    this.subdirs = {}; 
    this.subdirCount = 0; 
} 

Folder.prototype.AddDir = function (name, DOM_rows) { 
    if (this.subdirs[name]) { 
     return null; 
    } 
    ++this.subdirCount; 
    return this.subdirs[name] = new Folder(name, DOM_rows, this); 
} 

,你可以從父刪除文件夾:

delete folder.parent.subdirs[folder.name]; 

這裏的預購版本:

Folder.prototype.RemoveDir = function (folder) { 
    if (this.subdirs[folder.name] === folder) { 
     var stack = [folder]; 
     while(stack.length > 0) { 
      var cur = stack.pop(); 
      // pre-order 
      delete cur.files; 
      // if there's other processing to be done, now's the time to do it 
      for (subdir in cur.subdirs) { 
       stack.push(cur.subdirs[subdir]); 
       delete cur.subdirs[subdir]; 
      } 
      // it's unnecessary to set subdir count, since 'cur' has been deleted 
      //cur.subdirCount = 0; 
     } 
     delete this.subdirs[folder.name]; 
     --this.subdirCount; 
    } 
} 

和遞歸後序版本:

Folder.prototype.RemoveChildren = function() { 
    for (subdir in this.subdirs) { 
     this.RemoveDir(this.subdirs[subdir]); 
    } 
} 

Folder.prototype.RemoveDir = function (folder) { 
    if (this.subdirs[folder.name] === folder) { 
     folder.RemoveChildren(); 
     folder.files = []; 
     delete this.subdirs[folder.name]; 
     --this.subdirCount; 
    } 
} 

而且迭代後序版本:

Array.prototype.top = function() { return this[this.length-1]; } 

Folder.prototype.RemoveDir = function (folder) { 
    if (this.subdirs[folder.name] === folder) { 
     var stack = [folder]; 
     while(stack.length > 0) { 
      var cur = stack.top(); 
      if (cur.subdirCount > 0) { 
       for (subdir in cur.subdirs) { 
        stack.push(cur.subdirs[subdir]); 
        delete cur.subdirs[subdir]; 
       } 
       cur.subdirCount = 0; 
      } else { 
       stack.pop(); 
       delete cur.files; 
       // other post-order processing 
      } 
     } 
     delete this.subdirs[folder.name]; 
    } 
} 

雖然,除非在處理時你需要採取額外的步驟g刪除文件&文件夾,簡單:

Folder.prototype.RemoveDir = function (folder) { 
    if (this.subdirs[folder.name] === folder) { 
    delete this.subdirs[folder.name]; 
    } 
} 

應該就足夠了。

+0

謝謝outis - 你在這個城市 - 和.top()原型+1。我需要釋放對DOM元素的引用,所以我不能只刪除對該文件夾的引用,以免在IE中冒內存泄漏的風險。 – 2009-11-20 04:15:54

1

一切都是javascript傳遞的值,所以「* cur = NULL」是不可能的。基本上,你這裏有下列選項如你所說

  • 如果你的文件夾層次結構有一個衆所周知的根,從根瀏覽尋父對象
  • 使用像DOM removeChild之

    • 使用的parentID(它在parent上被調用),而不是removeNode(它在節點本身被調用)。
  • +0

    你的意思是通過引用? – 2009-11-19 23:31:25

    +1

    展開:Javascript是按值傳遞的,但對象是按引用存儲的。它有時被稱爲「通過參考值」。這就是爲什麼'function foo(obj){obj.qux = 1;}'的影響在調用'foo'之外是可見的,但不是'function bar(obj){obj = {qux:1};} 。 – outis 2009-11-20 00:20:05

    +0

    @outis:同意,只有原始參數('string','number','boolean','null'和'undefined')被「按值」傳遞,對象被「通過引用」傳遞(或者如你所說,該引用被傳遞爲值:)。 – CMS 2009-11-20 01:47:19

    1

    我今天想要做同樣的事情。 我已經通過將對象的索引存儲爲對象本身的屬性來解決它。

    當你添加:

    myObj.ID = myArr.push(myObj); 
    

    所以要去除它,你

    myArr[myObj.ID] = null; 
    

    我猜你解決它現在,但你可以做幾乎是相同的;這比使用對象更簡單。