Ryan Stonebraker Ryan Stonebraker - 25 days ago 6
Javascript Question

Updating properties of JS "class" based on other properties?

I'm relatively new to Javascript and I am trying to create a very simple physics engine for a game type project I am working on. In order to do this, I created what I understand to be the JS equivalent of a class that I can create new copies of for each object I want. The problem is that I want to be able to update a value such as the x position and have this also update things such as the x Middle position (x center of object on screen). I know this is possible by using an object literal and the getter, however I want to be able to create new objects at realtime based on what's on the screen and I couldn't figure out how to use get to make this work. Here's the general idea of what I am trying to do:

var object = function (xPos, yPos, width, height) {
this.xPos = xPos;
this.yPos = yPos;
function getXMid (xP) { return xP + width/2; }
this.xMid = getXMid (this.xPos);
function getYMid (yP) { return yP + height/2; }
this.yMid = getYMid (this.yPos);
}

var ball = new object (10, 20, 50, 50);
ball.xPos = 50;
console.log (ball.xMid); // want this to output 75 instead of 45

Answer

You're changing one property, and expecting other properties to update, unfortunately it doesn't work that way when the properties hold primitive values.

You could use setters and getters and a function to update the other properties when you set a value

var object = function(xPos, yPos, width, height) {
    this._xPos  = xPos;
    this._yPos  = yPos;
    this.recalc = function() {
    	this.xMid = getXMid(this.xPos);
        this.yMid = getYMid(this.yPos);
    }
    
    Object.defineProperty(this, 'xPos', {
        get: function() {
            return this._xPos;
        },
        set: function(v) {
        	this._xPos = v;
        	this.recalc();
        }
    });

	Object.defineProperty(this, 'yPos', {
        get: function() {
            return this._yPos;
        },
        set: function(v) {
        	this._yPos = v;
        	this.recalc();
        }
    });
    
    function getXMid(xP) { return xP + width / 2; }
    
    function getYMid(yP) { return yP + height / 2; }
    
    this.recalc();
}

var ball = new object(10, 20, 50, 50);
ball.xPos = 50;
console.log (ball.xMid); // want this to output 75 instead of 45