kornfridge kornfridge - 4 years ago 81
Javascript Question

How to add methods to a (JSON) object's prototype?

Let's say I receive some JSON object from my server, e.g. some data for a Person object:

{firstName: "Bjarne", lastName: "Fisk"}


Now, I want some methods on top of those data, e.g. for calculating the fullName:

fullName: function() { return this.firstName + " " + this.lastName; }


So that I can

var personData = {firstName: "Bjarne", lastName: "Fisk"};
var person = PROFIT(personData);
person.fullName(); // => "Bjarne Fisk"


What I basically would want to do here, is to add a method to the object's prototype. The
fullName()
method is general, so should not be added to the data object itself. Like..:

personData.fullName = function() { return this.firstName + " " + this.lastName; }


... would cause a lot of redundancy; and arguably "pollute" the data object.

What is the current best-practice way of adding such methods to a simple data object?

EDIT:

Slightly off topic, but if the problem above can be solved, it would be possible to do some nice pseudo-
pattern matching
like this:

if ( p = Person(data) ) {
console.log(p.fullName());
} else if ( d = Dog(data) ) {
console.log("I'm a dog lol. Hear me bark: "+d.bark());
} else {
throw new Exception("Shitty object");
}


Person
and
Dog
will add the methods if the
data
object has the right attributes. If not, return falsy (ie. data does not match/conform).

BONUS QUESTION: Does anyone know of a library that either uses or enables this (ie makes it easy)? Is it already a javascript pattern? If so, what is it called; and do you have a link that elaborates? Thanks :)

Answer Source

Assuming your Object comes from some JSON library that parses the server output to generate an Object, it will not in general have anything particular in its prototype ; and two objects generated for different server responses will not share a prototype chain (besides Object.prototype, of course ;) )

If you control all the places where a "Person" is created from JSON, you could do things the other way round : create an "empty" Person object (with a method like fullName in its prototype), and extend it with the object generated from the JSON (using $.extend, _.extend, or something similar).

var p = { first : "John", last : "Doe"};

function Person(data) {
   _.extend(this, data);
}

Person.prototype.fullName = function() {
   return this.first + " " + this.last;   
}

console.debug(new Person(p).fullName());
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download