将动态id属性添加到对象的键

时间:2015-11-25 17:50:22

标签: javascript

假设我们有一个类:

 function Parent() {
    this.pool = []
 }

 Parent.prototype.addChild = function(instance) {
    instance.id = this.pool.length + 1;
    this.pool.push(instance);

    return this;
 };

 Parent.prototype.removeChild = function(index) {
    this.pool.splice(index, 1);
 };

 function Child() {
      //something
 }

所以,我的意思是:

var task = new Parent(),
    child = new Child(),
    child2 = new Child(),
    child3 = new Child(),
    child4 = new Child();
task.addChild(child).addChild(child2).addChild(child3).addChild(child4);

如果我们在console.log task.pool中添加这一点,它将显示和收集ID为1,2,3,4的对象。

所以让我们删除3:

tasks.removeChild(2);

现在tasks.pool将显示集合,但是1,2,4。

如何通过引用创建id,这意味着,如果我删除3,那么4将更改为3,所以我们保持数字顺序没有任何差距?

2 个答案:

答案 0 :(得分:1)

  

如何通过引用创建id,这意味着,如果我删除3,那么4将更改为3,所以我们保持数字顺序没有任何差距?

要做到这一点,你要么:

  1. 进行更改后循环访问池,更新Child id

  2. Child个实例提供对池的引用,让它们根据它们在池中的位置动态生成id值(例如,使用getter函数)

  3. id查找方面,

    #1会更有效率。 #2可能不太容易出现实现错误(例如,在池上执行操作而忘记更新id值)。但它也增加了ChildParent之间的耦合,这通常不是一个好主意。

    #1的实例

    var Parent = (function() { // To give us a private scope for utility funcs
      function Parent() {
        this.pool = []
      }
    
      Parent.prototype.addChild = function(instance) {
        instance.id = this.pool.length + 1;
        this.pool.push(instance);
    
        return this;
      };
    
      Parent.prototype.removeChild = function(index) {
        this.pool.splice(index, 1);
        fixupIds(this.pool);
      };
    
      function fixupIds(pool) {
        pool.forEach(function(instance, index) {
          instance.id = index + 1;
        });
      }
    
      return Parent;
    })();
    
    function Child() {
      //something
    }
    
    var task = new Parent(),
      child = new Child(),
      child2 = new Child(),
      child3 = new Child(),
      child4 = new Child();
    task.addChild(child).addChild(child2).addChild(child3).addChild(child4);
    snippet.log(JSON.stringify(task, null, 2));
    task.removeChild(2);
    snippet.log(JSON.stringify(task, null, 2));
    <!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
    <script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

    我没有做#2的现场例子。坦率地说,我真的,真的不会这样做。 :-)但是如果你这样做了,你可以使用Object.definePropertyid上定义一个Child.prototype属性,该属性看起来是孩子们在池中(孩子必须知道它的池)。

答案 1 :(得分:1)

您可以在添加子项时指定一个id,然后通过过滤现有的子项来删除它,而不是将子项的id与QApplication数组中的索引相关联:

pool

或者,您可以function Parent() { this.pool = []; this._idCount = 0; } Parent.prototype.addChild = function(instance) { instance.id = this._idCount; this._idCount += 1; this.pool.push(instance); return this; }; Parent.prototype.removeChild = function(id) { this.pool = this.pool.filter(function(child) { return child.id !== id; }); }; function Child() { //something } 接受子对象而不是ID,然后您可以使用removeChildindexOf或使用splice轻松查找和删除该子对象

您还可以通过使用filter将子实例与其生成的ID相关联来避免完全改变子项。这样可以将多个子节点添加到多个父节点而不会发生ID冲突:

Map