开发者

Javascript - Remove references to my object from external arrays

I have a problem with dereferencing a Javascript object and setting it to NULL.

Here, I have a Folder implementation that supports recursive subdirectory removal. Please see my comments to understand my dilemma.

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开发者_如何学C.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?
      }
   }
}


Note that you don't have as big a problem as you suspect, since all subdirectories but folder in your RemoveDir will be deleted from their parent's subdir by the stack.push(cur.subdirs.pop()); line

To find a subdirectory in a parent, you could make use an object-as-dictionary rather than an array for 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);
}

Given a folder, you can remove the folder from the parent with:

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

Here's a preorder version:

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;
  }
}

And the recursive post-order version:

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;
    }
}

And the iterative post-order version:

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];
  }
}

Though, unless you need to take additional steps when processing deleted files & folders, a simple:

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

should suffice.


Everything is javascript is passed by value, so "*cur=NULL" is not possible. You basically have the following options here

  • use parentID as you suggested
  • if your Folder hierarchy has a well-known root, browse from that root to find the parent object
  • use something like DOM removeChild (which is called on parent), instead of removeNode (which is called on the node itself).


I was trying to do the same thing today. I've worked around it by storing the object's index as a property of the object itself.

When you add it:

myObj.ID = myArr.push(myObj);

So to remove it you

myArr[myObj.ID] = null;

I guess you solved it by now, but you could do almost the same; and it's simpler than using objects.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜