Jump to content

How to Circumvent Prototype Shared Objects Without Initializing?


MrFish
 Share

Recommended Posts

Here is my problem. I have a class called a DefinitionMap which will act as a Controlling class. It will have definitions for fields like- name = "[first_name] [last_name]" which will parse to "John Smith". The actual definitions will be stored in an object called "definitions". This class needs to use prototype and extend a class called StandardObject but that's irrelevant here (but I do need to use prototype for this).

 

Here is my basic DefinitionMap class.

function DefinitionMap(){}DefinitionMap.prototype.definitions = {};// ModifiersDefinitionMap.prototype.define = function(field, definition){	this.definitions[field] = definition;}// AccessorsDefinitionMap.prototype.get = function(field){return this.definitions[field];}

The problem with this is that definitions is already defined and all Objects constructed from this class will share the definitions object unless it's redefined within the objects own scope. Here is an example of what I mean-

 

http://jsfiddle.net/4JGMf/1/

 

You can see here that Definition1 defines "test_field" but Definition2 automatically has access to it.

 

One way to get around this without any forethought would be to treat the DefinitionMap(){} function as the constructor and define definitions in it. This works until you create a subclass on the DefinitionMap. I will eventually want to create preset definitions for different Model classes.

function DefinitionMap(){    this.definitions = {};}DefinitionMap.prototype.definitions = null;

http://jsfiddle.net/pvTju/1/

 

This can all be solved (with hassle) by creating an init method and call that method whenever a new object is constructed on one of these classes. You can try to call the init class automatically in the DefinitionMap constructor but this still doesn't work for subclasses.

function DefinitionMap(){    this.init();}DefinitionMap.prototype.definitions = null;// ModifiersDefinitionMap.prototype.init = function(){    this.definitions = {};   }

Will work be reluctant to use-

Definition1 = new PersonDefinition();Definition1.init(); // it hurts to liveDefinition2 = new PersonDefinition();Definition2.init(); // please kill me

http://jsfiddle.net/R77wP/1/

 

The first test makes sense because the definitions variable is assigned to an object created in the window scope. The second also makes sense because the subclass prototype creates a new object on the parent class once so any reference to the parent classes variables will point to one instance of the class.

 

Any practical work-arounds for this?

Edited by MrFish
Link to comment
Share on other sites

The second option is more correct, but you need to do more than just setting the prototype to an instance of the parent. Specifically, you need to copy properties and methods instead of using the same ones. Most Javascript frameworks have ways to do that, there is a short article describing one way to do it here:

 

http://www.htmlgoodies.com/html5/javascript/extending-javascript-objects-in-the-classical-inheritance-style.html

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...