Javascript apply methods from one object to another
I have been at this for hours and just can't get it quite right. I have an object with methods that works fine. I need to save it as a string using JSON.stringify and then bring it back as an object and still use the same methods.
function Workflow(){
this.setTitle = function(newtitle){this.title = newtitle; return this;};
this.getTitle = function(){return this.title;};
}
function testIn(){
var workflow = new Workflow().setTitle('Workflow Test');
Logger.log(workflow);//{title=Workflow Tes开发者_开发技巧t}
Logger.log(workflow.getTitle()); //Workflow Test
var stringy = JSON.stringify(workflow);
var newWorkflow = Utilities.jsonParse(stringy);
Logger.log(newWorkflow); //{title=Workflow Test}
//Looks like the same properties as above
Logger.log(newWorkflow.getTitle());//Error can't find getTitle
}
I think I should prototype the new object but nothing seems to work. Please help I have very little hair left.
You need to copy the method to the new object:
newWorkflow.getTitle = workflow.getTitle;
you are losing your functions when you stringify and parse. if you have access to jquery, the $.extend is handy (if not, just copy&paste form jquery source)
here's a demo: http://jsfiddle.net/VPfLc/
Serializing to JSON won't store executable code. It's being removed from your object when calling JSON.stringify. Your best bet is to make the object so it can be initialized when created.
function Workflow(){
this.initialize = function(properties) { this.title = properties.title; }
this.setTitle = function(newtitle){this.title = newtitle; return this;};
this.getTitle = function(){return this.title;};
}
function testIn(){
var workflow = new Workflow().setTitle('Workflow Test');
Logger.log(workflow);//{title=Workflow Test}
Logger.log(workflow.getTitle()); //Workflow Test
var stringy = JSON.stringify(workflow);
var newWorkflow = new Workflow().initialize(Utilities.jsonParse(stringy));
Logger.log(newWorkflow); //{title=Workflow Test}
//Looks like the same properties as above
Logger.log(newWorkflow.getTitle());//Error can't find getTitle
}
All you have to do is use call
.
Workflow.call(newWorkflow);
EDIT:
If your actual Workflow()
implementation sets any attributes to default values during its initilization then calling on your new json object will also reset those. Which is what I'm assuming is going on, without being able to look at your actual implementation code.
If that is the case, then you have two options.
1) Rather than blindly initilize your object (and assuming its empty), conditionally initilize your variables.
function Workflow(){
this.setTitle = function(newtitle){this.title = newtitle; return this;};
this.getTitle = function(){return this.title;};
this.array = this.array || [];
}
for new empty objects. this.array
will be null, and it'll be set to a new array. calling Workflow
on a existing object that already has that property, it'll leave it alone.
2) Extract your methods into an Extension Module
function Workflow(){
this.array = this.array || [];
// Other work
// Lastly include my method extensions.
WorkflowMethodExtensions.call(this);
}
function WorkflowMethodExtensions(){
this.setTitle = function(newtitle){this.title = newtitle; return this;};
this.getTitle = function(){return this.title;};
}
Then use:
WorkflowMethodExtensions.call(newWorkflow);
to extend an existing object with those methods defined in the existion
精彩评论