在es6中克隆一个类

时间:2016-02-14 06:50:06

标签: javascript class ecmascript-6

es6新手在这里,

我正在尝试创建一个具有另一个类作为其属性的类。

我的问题是我无法'克隆'该类的属性。

如下所示,我的目的是使用Component.getAll()静态方法仅返回MyClass实例中创建的项目。

我已经尝试过寻找一些东西,'mixins'出现了,但我不相信这会解决我的问题。

'use strict'
class Component {
  constructor(id) {
    this.id = id
    Component.addItem(this)
  }

  static addItem(item) {
    if (!this._items) {
      this._items = []
    }
    this._items.push(item)
  }

  static getAll() {
    return this._items
  }

  static getById(id) {
    return this._items.find(i => i.id === id)
  }
}


class MyClass {
  constructor(things) {

    //This is where my issue is.
    this.Component = Component


    things.forEach(t => new Component(t))
  }
}

function showIds(divId, items) {
  let ids = items.map(i => i.id)
  document.getElementById(divId).innerHTML = ids.toString()
}

let a = new MyClass([1, 2, 3])
a.Component.getById(1) //-> returns what is expected
let aItems = a.Component.getAll() // -> [1,2,3]
showIds('a', aItems)

//I would like b.Component.getAll() to only output -> [4,5,6]
//But because i can;t 'clone' the class, Its just adding the items into the same bucket. 
let b = new MyClass([4, 5, 6])
b.Component.getById(1) //-> should return undefined
let bItems = b.Component.getAll() // -> [1,2,3,4,5,6]
showIds('b', bItems)
<div id="a">
</div>

<div id="b">
</div>

声明Component类INSIDE MyClass似乎可以解决这个问题......但是在使用requireimport

时感觉会变得混乱

'use strict'



class MyClass {
  constructor(things) {

    class Component {
      constructor(id) {
        this.id = id
        Component.addItem(this)
      }

      static addItem(item) {
        if (!this._items) {
          this._items = []
        }
        this._items.push(item)
      }

      static getAll() {
        return this._items
      }

      static getById(id) {
        return this._items.find(i => i.id === id)
      }
    }

    this.Component = Component


    things.forEach(t => new Component(t))
  }
}

function showIds(divId, items) {
  let ids = items.map(i => i.id)
  document.getElementById(divId).innerHTML = ids.toString()
}

let a = new MyClass([1, 2, 3])
let aItems = a.Component.getAll() // -> [1,2,3]
showIds('a', aItems)

 
let b = new MyClass([4, 5, 6])
let bItems = b.Component.getAll() // -> [4,5,6]
showIds('b', bItems)
<div id="a">
</div>

<div id="b">
</div>

我很感激任何建议!

2 个答案:

答案 0 :(得分:3)

静态方法针对每个类设计为单个。如果你希望它们不是单一的,你可能不需要静态方法。

您可以添加一个名为ComponentsCollection的额外课程,为您进行Component跟踪。让我们从Component

移动所有静态方法
class Component {
  constructor(id) {
    this.id = id
  }
}


class ComponentsCollection {
  constructor() {
    this._components = [];
  }

  createComponent(id) {
     const component = new Component(id);
     this.components.push(component);
     return component;
  }

  getAll() {
    return this._components;
  }
}

然后您可以在ComponentsCollection中实例化MyClass并使用它来创建组件

class MyClass {
  constructor(things) {
    this.collection = new ComponentsCollection();

    things.forEach(t => this.collection.createComponent(t));
  }
}

检查出来:

let a = new MyClass([1, 2, 3])
console.log(a.collection.getAll().map(i => i.id))  // [1,2,3]
let b = new MyClass([4, 5, 6])
console.log(b.collection.getAll().map(i => i.id))  // [4,5,6]

答案 1 :(得分:1)

  

如下所示,我的目的是使用Component.getAll()静态方法仅返回MyClass实例中创建的项目。

问题是只有一个Component类和一个Component._items属性(和值)。 MyClass的每个实例(间接)访问相同的 Component._items值。

  

声明Component类INSIDE MyClass似乎可以解决这个问题......

是的,因为现在每个实例都有自己的Component类。

  

但使用requireimport

时感觉会变得混乱

我不知道怎么做。

但是,我确实同意在另一个类的构造函数中创建一个类似乎很奇怪。也许跟踪Component个实例不应该是Component本身的一部分,而应该是MyClass的一部分。

无论您选择哪种解决方案,每个实例都必须拥有自己的数组,以跟踪其Component个实例。