-1

I want to turn a plain JavaScript object into one with a prototype etc, without cloning the object. Is this possible?

Essentially, instead of this:

var MyClass = function(fromObj) {
  this.propA = fromObj.propA;
  this.propB = fromObj.propB;
  ...
}
inherit (SuperClass, MyClass);

I would like to:

var MyClass = function(fromObj) {
  this = fromObj;
}
inherit (SuperClass, MyClass);

To be extra clear: I would like the object returned from the constructor to be the same object that was passed in (not a duplicate, not a clone).

Is there a way to achieve this? Or a better way to describe what I'm asking for? :)

I'd like this for two reasons:

  1. We're loading a lot of objects, and speed and memory may start to matter.
  2. There are lots of places where the "plain old javascript objects" are used, and it may be hard to make sure they all point to the new instantiated object.
Steve Bennett
  • 114,604
  • 39
  • 168
  • 219
  • What do you mean, "without duplicating"? You do or don't want to affect the other Object after function is executed? Clone is used to describe a new instance. – StackSlave Oct 14 '15 at 22:46
  • 1
    passing an object by reference? http://stackoverflow.com/questions/13104494/does-javascript-pass-by-reference – GrafiCode Oct 14 '15 at 22:47
  • Clarified, @PHPglue - no duplication. I do want it to affect the other (well, the same) object. – Steve Bennett Oct 14 '15 at 22:49
  • You can just make a variable = Object, then variable.property = will affect Object. `var whatever = new ConstructorHere(), again = whatever;` – StackSlave Oct 14 '15 at 22:50
  • I know that's true generally, but does that work for a constructor? Remember, my constructor wants to take an object as an argument - the data has already been loaded from JSON elsewhere. – Steve Bennett Oct 14 '15 at 22:53
  • A Constructor becomes an Object when it's called. – StackSlave Oct 14 '15 at 22:55
  • An Object Literal is a new Object(). – StackSlave Oct 14 '15 at 23:04
  • 1
    So effectively you just want to assign the internal `[[Prototype]]` property of the passed in object to that of the constructor's prototype, effectively the opposite of `Object.create(prototypeObject)`. See [*Object.setPrototypeOf*](http://www.ecma-international.org/ecma-262/6.0/index.html#sec-object.setprototypeof). Also see [*MDN*](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf) and warnings about performance. – RobG Oct 14 '15 at 23:50
  • Wow, stern warnings. And ES6 only. I think I won't do that. :) – Steve Bennett Oct 14 '15 at 23:58
  • There are many poor explanations of Objects, on many JavaScript supporting websites. functions with properties are not really Objects until they are called with `new`. The function really has the `prototype` property, which is the Object from which it inherits it's properties. You can add a `prototype` property to an Object, but it does not have that property. `var what = {prop:'value'}; console.log(what.prototype)`. – StackSlave Oct 15 '15 at 00:15
  • @PHPglue: Please don't confuse the OP. He knows what he wants and has clearly and correctly described it. He does not misunderstand inheritance prototypes for `.prototype` properties. – Bergi Oct 15 '15 at 00:53
  • Everything that is not a primitive datatype is an instance of Object, which has a `prototype` property. This does not mean that your new instance of your Object has a `prototype` property. – StackSlave Oct 15 '15 at 01:46

1 Answers1

1

I guess you want to do this so that the objects created by JSON.parse are instances of something other than Object.

One option is to assign a new [[Prototype]] that is from the specified constructor using Object.setPrototypeOf, however there are performance warnings for this on MDN (I have no idea on the validity of the claims).

A more efficient solution might be to create "wrapper" objects and attach those created by JSON as a property. This approach is used by a number of DOM libraries and avoids the possibility of property names from the JSON data clashing with method names of the object (e.g. the DOM libraries can use methods with the same name and characteristics as DOM methods, but don't overwrite or clash with them).

Data could be held in a closure so that only getters and setters defined by the constructor can access it.

RobG
  • 142,382
  • 31
  • 172
  • 209