Calling methods in Javascript, without really calling them

Update: I think some people take this a bit too seriously: It’s a fun little experiment: nothing more, nothing less.

Sometimes you’re just lazy. Especially when it comes to typing. And while the round brackets in a function call may not seem like a whole lot of overhead, they do get tiresome if you have to type them over and over again… especially if you don’t think you need them since the function doesn’t return anything and needs no arguments: Something that’s awfully common in object-oriented UI programming.

Surprisingly enough, this isn’t all that difficult to do in Javascript, since a lot of methods are called implicitly… toString is probably the most famous one, but there’s also valueOf that does more or less the same but is called for numeric (and some other) casts.

The simplest way to call it is including a sign:

+myFunction;

which effectively translates to

window.parseFloat(myFunction.valueOf());

so all we need to do is provide a valueOf method that calls the function itself, like so:

Function.prototype.valueOf=function(){this.call(this); return 0;};

and suddenly the plus sing is all that’s needed for our call.

Especially in an object oriented environment you’ll have a lot of these calls, but you’ll have to fix the scope since these methods would be called in the scope of the method itself:

Function.prototype.fix=function(s){var t=this; return function(){ return t.apply(s,arguments); }; };

Using this method in the constructor to overwrite each method with a fixed-scope wrapper solves this:

var Foo=function(){
  this.myMethod=this.myMethod.fix(this);
};

or a bit more automated:

var Foo=function(){
  for(var i in this)
    if(typeof(this[i])=="function")
      this[i]=this[i].fix(this);
};

and finally we end up with this whole example (after a bit of OOP refactoring):

var StandardClass=function(){};
  StandardClass.prototype.initMethods=function(){
    for(var i in this)
      if(typeof(this[i])=="function" && this[i].dontWrap!==true)
        this[i]=this[i].fix(this);
};
StandardClass.prototype.initMethods.dontWrap=true;

Function.prototype.fix=function(s){
  var t=this;
  return function(){
    return t.apply(s,arguments);
  };
};

Function.prototype.valueOf=function(){
  this.call(this);
  return 0;
};

var Foo=function(name){
  this.initMethods();
  this.name=name;
};
Foo.prototype=new StandardClass;

Foo.prototype.showName=function(){
  alert(this.name);
};

Foo.prototype.showNameUpperCase=function(){
  alert(this.name.toUpperCase());
};

var myFoo=new Foo("Hello World");

+myFoo.showName;
+myFoo.showNameUpperCase;

20 thoughts on “Calling methods in Javascript, without really calling them”

  1. WHOW nice find. is it useful? …not sure. but the crockford factor on this one is huge.

  2. So what you’ve done is added about 25 ish lines of code to remove a single character? Maybe I’m missing something, but this really doesn’t seem useful to me.

  3. I once used this technique to make getter functions look like properties. I thought this would aid some junior developers on a large project.

    But then I wisely chose a different design pattern. 😀

  4. Well, it’s only 25 lines is only if you don’t already wrap your method-properties into scoped methods. On a typical OOP-JS project it only really adds 4 lines (or a single long one, depending on how you format you code):

    Function.prototype.valueOf=function(){this.call(this);return 0;};

    Of course it adds some overhead and there are lots of cases where this makes things noticeably slower, but there are still plenty of cases where a single function call more won’t make much of a difference.

  5. P.S. My personal typing habits also come into play here: I love to use only letters and the numpad: Combinations not so much. There’s a “+” key on my numpad, but no brackets.

  6. Very nice find 🙂
    Anyone decompiling a source that uses this technique is going to have a very hard time to figure out what the hell is going on :p

  7. If you use a compressor that also strips variable names he might really be in for a fun ride 🙂

  8. Seriously dude…why no brackets? My pet peeve is JS coders who leave out { and }.

    I’m sure you think it looks cleaner or some nonsense like that, but you’re making your code difficult to read, less portable, and more buggy.

    For the love of all that is holy people, stop leaving stuff out…

  9. Actually, I love leaving out { and }: It dramatically reduces the clutter without sacrificing any readability (if you format your code right), instead of bloating up your code with hundreds of lines that contain either “{” or “}”: Nothing worse that code that uses the BRACKET-NEWLINE-ELSE-NEWLINE-BRACET notation: 5 pages of code, 2 of which are typically lines consisting only of curly brackets.

    But that’s is not what this is about: it was a fun little experiment to see how you can use and abuse valueOf. In order to be comfortable with a language you just have to experiment and have a little fun with it. I wouldn’t use this is a project, still: I’m glad I tried.

  10. Actually I find this not as only a fun experiment but as an useful tip. It produces cleaner code and this is not a nonsense.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.