0

I have this code:

var Person = {
 "name": "",
 "changes": {
  "name to": function(value) {
   this["name"] = value;
  }
 }
}

var Josh = Object.create(Person);
Josh["changes"]["name to"]("John");

console.log(Josh.name); // nothing
console.log(Josh.changes.name); // "John"

The problem is that this above refers to Object "changes" and not object instance "Josh".

I can't replace this with Person because then it's referring to the object "Person" and not to the object instance "Josh".

Is it possible to refer to Josh's name?

MPelletier
  • 16,256
  • 15
  • 86
  • 137
ajsie
  • 77,632
  • 106
  • 276
  • 381
  • What is the "changes" object for? It doesn't appear to serve any purpose. It'd be more natural to have a `Person.changeName()` function. – John Kugelman Nov 28 '10 at 08:33
  • This was just a simplification of the actual implementation. The principle is the same though. – ajsie Nov 28 '10 at 08:34
  • 1
    From an OO pov, it seems a bit strange. An object is supposed to encapsulate data and methods to operate on that data. You're isolating your methods to another object. – Martin Algesten Nov 28 '10 at 08:47

2 Answers2

2

Why don't you use the more common form of Javascript OOP?

function Person() {
    this.name = "";
    this.changes = {};
    var _this = this;
    this.changes.nameTo = function(name) {
        _this.name = name;
    }
}

var Josh = new Person();
Josh.changes.nameTo("John");

console.log(Josh.name); // "John"
console.log(Josh.changes.name); // undefined
Eric
  • 95,302
  • 53
  • 242
  • 374
0

Sadly not. You don't have any reference to an enclosing instance of the object you're in currently. You need to move the method to the outer Person object.

var Person = {
 "name": "",
 "changeNameTo": function(value) {
   this["name"] = value;
 }
}

Edit: If you absolutely want the original structure, albeit strange from an OO perspective. You need to give the inner object a reference to the outer. Programatically you can do it as below - or perhaps do it in a constructor, depending on your framework providing the Object.create() method.

var Person = {
 "name": "",
 "changes": {
  "name to": function(value) {
   this.data["name"] = value;
  }
 }
}

var Josh = Object.create(Person);
Josh.changes.data = Josh;

Josh["changes"]["name to"]("John");
Martin Algesten
  • 13,052
  • 4
  • 54
  • 77
  • Isn't it possible to use caller/callee to get the first object called: Josh["changes"]["name to"]("John") which in this case is Josh? – ajsie Nov 28 '10 at 08:38
  • Ha! Yeah, I suppose - but that's so obscure, I'd completely forgotten about it. Seems it's deprecated even http://stackoverflow.com/questions/103598/why-was-the-arguments-callee-caller-property-deprecated-in-javascript – Martin Algesten Nov 28 '10 at 08:41
  • Do you know how I could use caller/callee in my case to get Object Josh? – ajsie Nov 28 '10 at 08:47
  • Hm.. on second thoughts, I was confused. `Josh["changes"]["name to"]("John");` The `arguments.callee` is the inner function, but `arguments.callee.caller` is (of course) not the outer. – Martin Algesten Nov 28 '10 at 08:56