Over a million developers have joined DZone.

JavaScript Gotcha for Pythonistas: Bound Methods

DZone's Guide to

JavaScript Gotcha for Pythonistas: Bound Methods

· Web Dev Zone
Free Resource

Learn how to build modern digital experience apps with Crafter CMS. Download this eBook now. Brought to you in partnership with Crafter Software

Today while writing some JavaScript code I ran into an interesting gotcha I wanted to briefly mention. It has to do with method binding; more specifically, the behavior I’m used to from Python. Here’s a code sample:

class MyKlass:
    def __init__(self):
        self.num = 2

        f = self.foo
        self.result = f(10)

    def foo(self, othernum):
        return self.num + othernum

mk = MyKlass()

The interesting part is invoking self.foo indirectly via f(). This works and prints 12 as expected. It works because the assignment f = self.foo assigns a bound method to f. By "bound", I mean that the method knows which object it belongs to, and when its body is executed self is set to the right thing.

The same does not hold in JavaScript. Here’s a straightforward translation:

'use strict';

var MyKlass = function() {
  this.num = 2;

  var f = this.foo;
  this.result = f(10);

MyKlass.prototype.foo = function(othernum) {
  return this.num + othernum;

var mk = new MyKlass();

This doesn’t work. I get an error from Node.js:

  return this.num + othernum;
TypeError: Cannot read property 'num' of undefined

So what’s going on? The reason is that, unlike in Python, the assignment f = this.foo does not assign a bound method to f. It’s simply a property lookup on the object this; it indeed has the property foo, which is a function. f now refers to that function. That’s it. There is no implicit binding going on.

Once the problem is understood, it’s easy to solve. The most direct solution is to bind the method explicitly on assignment, using Function.prototype.bind:

var bound_f = this.foo.bind(this);
this.result = bound_f(10);

An alternative solution is not to bind foo when a new reference to it is made, but do it when it’s invoked through that reference. This can be done using Function.prototype.call (or equivalently using its cousin apply):

var f = this.foo;
this.result = f.call(this, 20);

This difference between the two languages exists because unlike Python, JavaScript does not have a first-class entity for a bound method. This is not surprising, because the Python method is bound to an instance, but instances in the "classical" sense don’t exist in JavaScript (see how the class and method concepts from "classical OO" are simulated above with JS’s constructor functions and prototypal inheritance).

What does exist in JavaScript is lexical binding and closures. While the bind method is new in ES5, its effect can be simulated very easily:

Function.prototype.bind = function(obj) {
  var self = this;
  return function () {
    return self.apply(obj, arguments);

Note that the actual implementation of bind would be just a little more complicated because bind also supports partial application of arguments (some of the arguments can be provided during binding, and the rest on invocation).


Crafter is a modern CMS platform for building modern websites and content-rich digital experiences. Download this eBook now. Brought to you in partnership with Crafter Software.


Published at DZone with permission of Eli Bendersky, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.


Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.


{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}