Search code examples
javascriptobjectcompositionassign

Javascript Object Composition with assign & Object.create


trying to wrap my head around javascript composition using assign. The property on my base object is unexpectedly being shared between instances. What am I doing wrong? I have...

Stat.js:

import assign from 'object-assign';
var Stat = assign({}, {
    _value: undefined,

    get: function() {
        return this._value;
    },

    set: function(n) { 
        var max = this.getMax();

        if(n > max) {
            this._value = max;
        } else {
            this._value = n; 
        }
    },

    getMax: function() {
        return 1;
    }
});
module.exports = Stat;

HitPoints.js:

import assign from 'object-assign'
import Stat from './Stat.js';

var HitPoints = assign({}, Stat, {        
    getMax: function() {
        return 100;
    }
});
module.exports = HitPoints;

Unit.js:

import assign from 'object-assign';
import HitPoints from 'HitPoints.js';

var Unit = assign({}, {
        hp: Object.create(HitPoints)
    }
);
module.exports = Unit; 

Usage:

import Unit from 'Unit.js';

var u1 = Object.create(Unit);
console.log( u1.hp.get() ); // undefined - ok
u1.hp.set(11);
console.log( u1.hp.get() ); // 11 - ok

var u2 = Object.create(Unit);
console.log( u2.hp.get() ); // 11 - ???
u2.hp.set(22);
console.log( u1.hp.get() ); // 22 - ???
console.log( u2.hp.get() ); // 22

Thanks for your help...


Solution

  • Well, this worked...

    Stat.js:

    var Stat = {
        get: function() {
            return this._value;
        },
    
        set: function(n) { 
            var max = this.getMax();
    
            if(n > max) {
                this._value = max;
            } else {
                this._value = n; 
            }
        },
    
        getMax: function() {
            return 1;
        }
    }
    

    HitPoints.js:

    var HitPoints = function() {
        return assign(Object.create(Stat), {    
            getMax: function() {
                return 100;
            }
        });
    }
    

    Unit.js:

    var Unit = function() {
        return assign({},
            Object.create(XYPiece),
            Object.create(TeamMember),
            {
                 hp: HitPoints()     
            }
        );                       
    }
    

    Usage:

    var u1 = Unit();
    console.log( u1.hp.get() ); // undefined
    u1.hp.set(11);
    console.log( u1.hp.get() ); // 11
    
    var u2 = Unit();
    console.log( u2.hp.get() ); // undefined
    u2.hp.set(22);
    console.log( u1.hp.get() ); // 11
    console.log( u2.hp.get() ); // 22
    

    This article helped. Hooray!!!

    Still, tho, if this is fundamentally an idiotic way to go about it, tell me...