Standard
Standard

Reputation: 1512

Javascript constructor: Accessing outside variable

I try to access an object which is global; it's a kind of a preset.

var perks = {health: 100, attack: 10};

var player = function(hp) {
   this.stats = perks;

   //Changing some standard values..
   this.stats["health"] = hp; 
}

var Peter = new player(200);
var Steven = new player(300);

I hope you get my intention; the problem is, that it won't work correct, and I'm not even sure what it does wrong. If I create more than one player, e.g. Steven, Collin and James, every player has the same perks. In this example Peter and Steven both have 300 health.

If I change the line

this.stats = perks;

to

this.stats = {health: 100, attack: 10};

everything works like intended. Peter and Steven both have their own stats. How do I access the global var perks?

Upvotes: 1

Views: 1546

Answers (2)

Andrew Surzhynskyi
Andrew Surzhynskyi

Reputation: 2776

It happens because in JavaScript object does not copy that way, thats why all of your players using the same perks object. There is a few ways to solve it:

  1. Create new object with a function (object own constructor).

    function createPerks() {
        return {
            health: 100,
            attack: 10
        };
    }
    
    var player = function(hp) {
        this.stats = createPerks();
    
        //Changing some standard values..
        this.stats["health"] = hp; 
    }
    
    var Peter = new player(200);
    var Steven = new player(300);
    
  2. Create new object each time and use constants for default values:

    var BASE_HEALTH = 100;
    var BASE_ATTACK = 10;
    
    var player = function(hp) {
        this.stats = {
            health: BASE_HEALTH,
            attack: BASE_ATTACK
        };
    
        //Changing some standard values..
        this.stats["health"] = hp; 
    }
    
    var Peter = new player(200);
    var Steven = new player(300);
    
  3. Use Object.create (works in IE9+, but shimable for older browsers):

    var perks = {health: 100, attack: 10};
    
    var player = function(hp) {
        this.stats = Object.create(perks);
    
        //Changing some standard values..
        this.stats["health"] = hp; 
    }
    
    var Peter = new player(200);
    var Steven = new player(300);
    

    Keep in mind that Object.create does not clone an object but inherit one object from another.

    Object.create shim for old browsers by Douglas Crockford:

    if (typeof Object.create !== 'function') {
        Object.create = function (o) {
            function F() {}
            F.prototype = o;
            return new F();
        };
    }
    

Upvotes: 2

Zee
Zee

Reputation: 8488

The moment you write this.stats = perks; both of them refer to the same object that is {health: 100, attack: 10}. So any changes made to any one of them will always affect the other.

As var Steven = new player(300); is the last value you assigned. All your players will now have {health: 300, attack: 10}

Upvotes: 1

Related Questions