【问题标题】:Passing variables using object composition in javascript在 javascript 中使用对象组合传递变量
【发布时间】:2019-03-17 13:03:06
【问题描述】:

一段时间以来,我一直在尝试围绕对象组合进行思考,但我似乎无法找到“正确的方法”来完成我之前使用 OOP 所做的事情。假设我有一个带有 3 个变量的类 Entity,使用 OOP 我只需创建一个类 Entity 并且该类的所有子级都将具有这 3 个属性,但是使用对象组合我似乎无法理解我应该如何模仿这种继承。

const Entity = {
    let self = {
         x: 0,
         y: 0,
         z: 0,
}

我是否需要在我创建的所有其他需要它们的对象中创建这些属性?或者有没有更好的方法来重用这些属性?

const ObjectX = {
     let state = {
        x: 0,
        y: 0,
        z: 0,
        abc: 0,
        cba: 0,
return Object.assign(state, canDoX);
}

const ObjectY = {
     let state = {
        x: 0,
        y: 0,
        z: 0,
        foo: 0,
        bar: 0,
return Object.assign(state, canDoY);
}

【问题讨论】:

  • 对象字面量不应在属性列表末尾有返回值或逗号。
  • 您向我们展示的代码甚至不会编译 const Entity = {} 是文字对象声明,应该遵循的是键/值对,但是您有一些 let self 语句,这绝对是不正确的,并且会自动抛出错误。
  • Entity and all the children of this class would have these 3 properties,在 Javascript 中你会使用原型,但首先你需要创建一个类,而不是一个对象..
  • @Keith 创建一个类很酷,但它只是语法糖,所以我不会说你需要创建一个,但也许你应该 b> 创建一个。我认为了解底层函数和对象在 javascript 中的工作方式很重要,以便了解 Class 在 javascript 中的工作方式。
  • @MatusDubrava 我一直在关注这个guide,所以我认为这是这样做的方法。

标签: javascript composition object-composition


【解决方案1】:

如果你想用另一个对象扩展(通过原型)某个对象,那么你可以使用Object.create 方法,它接受一个对象作为参数并创建一个新对象,这个传入的对象通过原型链链接到它。

const entity = {
    x: 1,
    y: 2,
    z: 3
};

const objectX = Object.create(entity);
objectX.abc = 'something';

console.log(objectX.x);
console.log(objectX.y);
console.log(objectX.z);
console.log(objectX.abc);

如果您只想将一个对象混合到另一个对象中,那么您可以使用Object.assign 并将一个空对象作为第一个参数,将entity 对象作为第二个参数传递给此方法,然后使用从entity 复制的所有属性(请注意,这只是一个浅拷贝,因此如果entity 包含其中的一些其他对象,则需要特别小心 - 这些将通过引用复制,因此您将改变原始的,如果你愿意更新它们)。

const entity = {
    x: 1,
    y: 2,
    z: 3
};

const objectX = Object.assign({}, entity);
objectX.abc = 'something';

console.log(objectX.x);
console.log(objectX.y);
console.log(objectX.z);
console.log(objectX.abc);

最后,Object.assign 可以被这样的对象解构替换。

const objectX = { ...entity };

但同样,这也只会产生一个浅拷贝。

【讨论】:

  • 谢谢你的回答,这绝对是我要找的。​​span>
【解决方案2】:

你可能想要一个构造函数?

function BatLoser(batterName){
  this.batter = batterName; this.balls = 0; this.strikes = 0; this.onBase = false; this.strikeOut = false;
  this.swing = function(){
    var zeroOneTwo = Math.floor(Math.random()*3);
    switch(zeroOneTwo){
      case 0:
        this.balls++;
        console.log('ball '+this.balls+' for '+this.batter);
        break;
      case 1:
        this.strikes++;
        console.log('strike '+this.strikes+' for '+this.batter);
        break;
      case 2:
        this.onBase = true;
        console.log(this.batter+' hits the ball and is on base');
        return this;
    }
    if(this.balls > 3){
      this.onBase = true;
      console.log(this.batter+' walks on base');
    }
    if(this.strikes > 2){
      this.strikeOut = true;
      console.log(this.batter+' struck out');
    }
    return this;
  }
  this.batterUp = function(){
    while(!this.onBase && !this.strikeOut){
      this.swing();
    }
    return this;
  }
}
var bob = new BatLoser('Bob'), joe = new BatLoser('Joe');
bob.batterUp(); console.log('-------'); joe.batterUp();

只需继续点击该按钮即可查看结果如何变化。

请注意,构造函数的每个 new 实例都会创建一个 new 对象。对象字面量没有 __constructor 方法,或者任何你习惯的方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多