0

When trying to create a new object, one that is empty for manipulation, I can't get the old data out.

Here is an example of what I've tried:

function Foo() {
    this.Bar = Bar;
    // etc..
}

var Bar = {
    __words : {},
    addWord : function (word, amount) {
        this.__words[word] = amount;
    }
    // etc..
}

Now, when I create a new object:

var foo = new Foo();
var bar = foo.Bar;
bar.addWord("hello",7);
bar.addWord("world",9);

var lorem = new Foo();
var words = lorem.Bar.__words; // This will display {hello:7,world:9} from the
                               // previous object

I also tried using Object.create() but it was still the same, showing the __words from the previous object.

Hairr
  • 1,088
  • 2
  • 11
  • 19

3 Answers3

4

The object referred to by Bar is shared between each Foo instance.

I don't really see the point of putting the logic into two objects, you can do this with just one constructor function:

function Foo() {
    this.__words = {};
}

Foo.prototype.addWord = function(word, amount) {
    this.__words[word] = amount;
}


var foo = new Foo();
foo.addWord("hello",7);

var bar = new Foo();
bar.addWord("world",9);

If you really have to separate the functionality, then make Bar a constructor function as well and create a new instance inside the Foo constructor method:

function Foo() {
    this.bar = new Bar();
}


function Bar() {
    this.__words = {};
}

Bar.prototype.addWord = function(word, amount) {
    this.__words[word] = amount;
}
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
0

I can't get the old data out.

Well you are not clearing var Bar which is global actually - meaning you are creating a new Object with var lorem = new Foo(); but giving him the same Bar Object with Foos constructor.

this.Bar = Bar; 

if you want a new Object you should give Foo its own Bar Object. Or include:

__words : {},
    addWord : function (word, amount) {
        this.__words[word] = amount;

in Foo itself.

Anyways if you just need this once, you could simply empty the words array in Bar.

Taryn
  • 242,637
  • 56
  • 362
  • 405
0

There are couple of problems in the code.

function Foo() {
    this.Bar = Bar;
    // etc..
}

var Bar = {
    __words : {},
    addWord : function (word, amount) {
        this.__words[word] = amount;
    }
    // etc..
}

Bar should be defined before Foo but it might work without problems because variables are actually defined at function scope level which might not be a problem in this particular example.

That said, you're copying an object inside the Foo constructor. Objects are mutables so it won't work. One change to the object will change the other. What you might be able to do is this. Here's an other way to do that without new.

var Bar = {
    create: function () {
       var obj = Object.create(this);
       obj.__words= {};
       return obj;
    },

    addWord: function (word, amount) {
       this.__words[word] = amount;
    }
    ...other methods...
};

var Foo = function () {
    this.Bar = Bar.create();
    // etc..
};

But I have no idea how is supported Object.create in other browsers. This is syntax is the equivalent to what Felix wrote, you could clearly remove the need of two object.

The only big difference is that instead of writing new Bar(). You are actually creating a prototype object and creating an object from the prototype. The create is the constructor.

Foo could be written in the same way and you'd get something like this.

var Bar = {
    create: function () {
       var obj = Object.create(this);
       obj.__words= {};
       return obj;
    },

    addWord: function (word, amount) {
       this.__words[word] = amount;
    },
    ...other methods...
};

var Foo = {
    create: function () {
      var foo = Object.create(this);
      foo.Bar = Bar.create();
      return foo;
    },
    ....
};

var foo1 = Foo.create();
var foo2 = Foo.create();

foo1.bar.addWord("allo", 3);

I guess it all depends on what you're trying to do but the create method as some advantages over the "new" operators. You could for example create async methods that after object creations execute a callback.

Over here for more informations. In the end it's pretty much the same thing.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create

Loïc Faure-Lacroix
  • 13,220
  • 6
  • 67
  • 99
  • Your solution won't work. The object in `Bar.__words` will be shared by all instances you create with `Object.create(Bar)`. You just moved the problem one level away (so to speak). – Felix Kling Jun 09 '13 at 21:06