2013-02-11

Calling JavaScript method references

This blog post is a documentation of a quirk in the JavaScript language: method calls and method reference calls don't operate on the same receiver (thisArg), i.e. cat.foo() and (cat.foo)() are not equivalent.

Example:

<script>
function Cat() {}
Cat.prototype.toString = function() { return 'CatObj'; };
Cat.prototype.foo = function() {
  document.write('<p>CATFOO ' + this);
};
function Dog() {}
Dog.prototype.toString = function() { return 'DogObj'; };
Dog.prototype.bar = function() {
  var cat = new Cat();
  cat.foo();          //: CATFOO CatObj
  (cat.foo)();        //: CATFOO [object Window]
  var catFoo = cat.foo;
  catFoo();           //: CATFOO [object Window]
  catFoo.call(cat);   //: CATFOO CatObj
  catFoo.call(this);  //: CATFOO DogObj
};
(new Dog()).bar();
</script>

The solution is to using built-in methods call or apply, and passing the receiver object (thisArg) as the first argument.