0

I've been trying to wrap my head around Object Composition for a while and I can't seem to find the "correct way" to do the same I was doing before with OOP. Lets say I have a class Entity with 3 variables, with OOP I would just create a class Entity and all the children of this class would have these 3 properties, but using object composition I can't seem to understand how I'm supposed to mimic this inheritance.

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

Do I need to create these properties in all other objects I create that need them? Or is there a better way to reuse these properties?

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);
}
10
  • Object literals should not have a return value or a comma at the end of the property list. Commented Oct 12, 2018 at 10:06
  • Code that you are showing us won't even compile const Entity = {} is literal object declaration and what should follow are key/value pairs, but you have some let self statement there which is definitely incorrect and will automatically throw an error. Commented Oct 12, 2018 at 10:07
  • Entity and all the children of this class would have these 3 properties, in Javascript you would use the protototype, but first you need to create a Class, not an Object.. Commented Oct 12, 2018 at 10:10
  • @Keith creating a class is cool, but it is just syntactic sugar, so I would not say you need to create one, but perhaps you should create one. I think it's important to understand how the underlying functions and objects work in javascript in order to understand how a Class works in javascript. Commented Oct 12, 2018 at 10:13
  • @MatusDubrava I've been following this guide so I assumed it was the way to do it. Commented Oct 12, 2018 at 12:43

2 Answers 2

1

If you want to extend (via prototype) some object with another object then you can use Object.create method which takes an object as argument and creates a new object with this passed in object linked to it via prototype chain.

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

If you just want to mix one object into another then you can use Object.assign and pass an empty object as the first argument and the entity object as the second argument to this method which will then create a new object with all the properties copied from the entity (note that this is only a shallow copy therefore you need to take some special care if that entity contains some other objects inside of it - those will be copied by reference therefore you would mutate the original ones if you would update them).

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

Last thing, Object.assign can be replaced by object destructuring like this.

const objectX = { ...entity };

But again, this also produces only a shallow copy.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for your answer, this is definitely what I was searching for.
0

You probably want a constructor?

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();

Just keep hitting that button to see how the results vary.

Note that every new instance of a Constructor creates a new Object. Object literals do not have a __constructor method, or whatever you are used to.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.