JavaScript Prototype Chain Mutator

In JavaScript world, JSON serialization is widely used. When fetching data from server via Ajax, the data is usually represented in JSON; or loading configuration/data from file in Node.js application, the configuration/data is usually in JSON format.

JSON serialization is powerful and convenient, but there is limitation. For security and other reason, behavior and type information are forbidden in JSON. Functions members are removed when stringify a JavaScript object, also functions are not allowed in JSON.

Comparing Yaml to Ruby, this limitation isn’t that convenient when writing JavaScript application. For example, to consume the JSON data fetched via ajax from server, I really wish I can invoke some method on the deserialized model.

Here is simple example:

Ideal World
1
2
3
4
5
6
7
8
9
10
11
12
13
class Rect
constructor: (width, height) ->
@width = width if width?
@height = height if height?
area: ->
@width * @height
$.get '/rect/latest', (rectJSON) ->
rect = JSON.parse(rectJSON)
console.log rect.area() # This code doesn't work because there is rect is a plain object

The code doesn’t work, because rect in a plain object, which doesn’t contains any behavior. Someone called the rect DTO, Data Transfer Object, or POJO, Plain Old Java Object, a concept borrowed from Java world. Here we call it DTO.

To add behaviors to DTO, there are variant approaches. Such as create a behavior wrapper around the DTO, or create a new model with behavior and copy all the data from DTO to model. These practices are borrowed from Java world, or traditional Object Oriented world.

In fact, in JavaScript, there could be a better and smarter way to achieve that: Object Mutation, altering object prototype chain on the fly to convert a object into the instance of a specific type. The process is really similar to biologic genetic mutation, converting a species into another by altering the gene, so I borrow the term mutation.

With the idea, we can achieve this:

Mutate rect with Mutator
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Rect
constructor: (width, height) ->
@width = width if width?
@height = height if height?
area: ->
@width * @height
$.get '/rect/latest', (rectJSON) ->
rect = JSON.parse(rectJSON)
mutate(rect, Rect)
console.log rect.area()

The key to implement mutate function is to simulate new operator behavior, alerting object.__proto__ and apply constructor to the instance! For more detail, check out the library mutator Bower version NPM version, which is available as both NPM package and bower package.

When implementing the mutator, in IE, again, in the evil IE, the idea doesn’t work. Before IE 11, JavaScript prototype chain for instance is not accessible. There is nothing equivalent to object.__proto__ in IE 10 and prior. The most similar workaround is doing a hard-copy of all the members, but it still fails in type check and some dynamical usage.

Background

object.__proto__ is a Mozilla “private” implementation until EcmaScript 6.
It is interesting that most JavaScript support it except IE.
Luckily, IE 11 introduced some features in EcmaScript 6, object.__proto__ is one of them.

Introduce Prototype Style OO inheritance in Ruby

Days ago, I post a blog about the ruby inheritance hierarchy. When discuss the topic with Yang Lin, he mentioned a crazy but interesting idea that introducing the prototype based OO into ruby.
To introducing the prototype OO into ruby, Lin mentioned a possible approach is by using clone. But I’m not familiar with clone mechanism in ruby. So I tried another approach.
Thanks to Ruby’s super powerful meta-programming mechanism, so I can forward the unknown message to prototype by using method_missing. And I encapsulate the code in a module, so every instance extended that module will obtain such capability.

Prototype Module
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
module Prototype
def inherit_from(prototype)
@prototype = prototype
self
end
def create_child
Object.new.extend(Prototype).inherit_from(self)
end
def respond_to?(msg_id, priv = false)
return true if super
if @prototype
@prototype.respond_to?(msg_id, priv)
else
false
end
end
def method_missing(symbol, *args, &block)
if @prototype
@prototype.send(symbol, *args, &block)
else
super
end
end
def self.new
Object.new.extend(Prototype)
end
end

If I have the following code:

Prototype Inheritance
1
2
3
4
5
6
7
8
9
10
11
12
13
a = Object.new
def a.foo
'foo'
end
b = Object.new
b.extend(Prototype).inherit_from(a)
c = b.create_child
p b.foo # => 'foo'
p c.foo # => 'foo'

So b.foo and c.foo will yield ‘foo’.

And I can override the parent implementation by refine a method with the same name:

Prototype Overrides
1
2
3
4
5
6
7
8
9
10
11
def a.bar
'bar'
end
def c.bar
'c.bar'
end
p a.bar # => 'bar'
p b.bar # => 'bar'
p c.bar # => 'c.bar'

So I add a new singleton method bar in a, and b automatically inherits the method, and I override the bar on object c.

As a conclusion that we’re able to introduce the prototype based inheritance in ruby by using ruby’s powerful meta-programming mechanism. This implementation is only for concept-proof, so its performance is not quite good. But we can try to improve the performance by consolidating process by defining the method dynamically. The child object will query the parent for the first time, if invoking succeeded then it can consolidate the behavior into a method to avoid calling method_missing every time.