Take the 2-minute tour ×

I'm looking to be able to extend the function prototype in javascript (that is to say, add a function to all functions). The purpose is to convert it into a format for exchange between another language (namely ruby, which can only communicate through strings [in this particular setting]). I've already got a system so I can pass around other types by defining a to_js method on ruby objects and a to_ruby method on javascript objects, like so

Number.prototype.to_ruby = function () { return this.toString(); }

This is working for everything else I want it to, but not for functions. I can get it to work in chrome by doing the following:

_empty = function() {};
_empty.__proto__.to_ruby = function () {
    return 'JSFunction.new(' + this.toString().to_ruby() + ')';

But this does not work in IE (which is a requirement of the system).

I know I have an object somewhere keeping a track of functions by an ID or similar, but I can't guarantee that they will be used with the same instance that created them.

All else failing I could just write a function to special case deal with it (ie, isFunction(instance) ? fn_to_ruby(instance) : instance.to_ruby(), but I'd rather keep this model if possible.

share|improve this question
Hah! I just happen to be looking into the same thing. SketchUp Ruby <-> JavaScript bridge. :D –  thomthom Jun 5 '13 at 12:16
add comment

3 Answers

up vote 0 down vote accepted

__proto__ is not a standard property. Try this approach:

(function(){}).constructor.prototype.to_ruby = function(){
share|improve this answer
Ah! Adding the .constructor gives me the functionality I was looking for - thanks! –  DanielB May 10 '12 at 6:30
You must get paid by the character. (function(){}).constructor.prototype is just Function.prototype. And calling someObj.to_ruby() will be identical to "" + someObj –  RobG May 10 '12 at 7:03
@RobG, you are correct - and of course now that I ca see it, it makes perfect sense. thanks :) –  DanielB May 10 '12 at 7:17
@RobG, don't get the point: ""+someObj, with someObj={a:1,b:2} returns "[object Object]" to me. and ({a:1,b:2}).prototype resolve to undefined –  Eineki May 10 '12 at 13:17
@Eineki—yeah, should have used someFn since the OP is about Functions, but you can replace Object.prototype.toString with a more suitable method (but be careful about sharing such code). –  RobG May 11 '12 at 3:22
add comment

As Slace said, you can add the method to all Objects by adding it to Object.prototype, but that isn't really kosher as it may affect badly written for..in loops.

You can add it just to functions via Function.prototype:

Function.prototype.to_ruby = function() {
  return this.toString();

However there is a general rule that you shouldn't modify built-in objects, mostly because you never know when it will come back to haunt you (e.g. a new version of ECMAScript implements a property with the same name). Perhaps you are better off to write a single toRuby function:

function toRuby(obj) {
  return obj.toString();

but you can also also use the + operator to concatenate with a string to call the toString method implicitly:

'' + obj; // returns obj.toString()

which will return exactly the same result as both the above. Your choice.

share|improve this answer
I understand your argument, but I've got a number of different types of objects that all need to return slightly differently. So this would work for basic types like numbers and strings (assuming they don't need to be escaped) but for arrays, hash-like objects and custom types I'd have to write a special case for each, and continue to edit that as I require more or less objects. –  DanielB May 10 '12 at 7:09
In that case you can write a single toRuby() function and tell it how to convert the passed object, e.g. toRuby(someFn, 'fn'), toRuby(someObj, 'obj') or similar. –  RobG May 11 '12 at 3:25
That's what I originally had, but as the number of possible object types increased I figured it would just be easier to have a to_ruby method on objects that supported the conversion. That way I could easily test for support as well as perform the conversion. –  DanielB May 11 '12 at 5:29
add comment

The __proto__ is not part of any JavaScript standard it's just a pesudo-standard that some of the browser manufacturers have decided to implement. IE is one that hasn't implemented it.

If you want to modify any type in the JavaScript type system then you'll have to modify the Object prototype:

Object.prototype.foo = function () { console.log('foo'); };
({ bar: 'baz' }).foo();
share|improve this answer
add comment

Your Answer


