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.
extend() Function. The _. extend() function is used to create a copy of all of the properties of the source objects over the destination object and return the destination object.
A function prototype begins with the keyword function, then lists the function name, its parameters (if any), and return value (if any). The prototype includes no executable code. You can use function prototypes in the following situations: When defining an ExternalType (see ExternalType part).
A function's prototype property, by default, is a plain object with one property: constructor , which is a reference to the function itself. The constructor property is writable, non-enumerable, and configurable.
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.
__proto__
is not a standard property. Try this approach:
(function(){}).constructor.prototype.to_ruby = function(){
return 'JSFunction.new(' + this.toString().to_ruby() + ')';
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With