Parit
Parit

Reputation: 152

Coffeescript-Javascript correlation

I am trying to understand how private methods are created using coffeescript. Following is an example code

class builders
constructor: ->
    // private method
    call = =>
            @priv2Method()
    // privileged method
    privLedgeMethod: =>
            call()
    // privileged method 
    priv2Method: =>
            console.log("got it")

Following is the generated JS code.

(function() { var builders, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; builders = (function() { var call, _this = this; function builders() { this.priv2Method = __bind(this.priv2Method, this); this.privLedgeMethod = __bind(this.privLedgeMethod, this); } call = function() { return builders.priv2Method(); }; builders.prototype.privLedgeMethod = function() { return call(); }; builders.prototype.priv2Method = function() { return console.log("got it"); }; return builders; }).call(this); }).call(this);

Note that I have used "fat arrow" for the function definition. There are couple of things that I didn't get from the code.

  1. what's the use of _this variable
  2. if you run this code as : (new builders()).privLedgeMethod() than inside the call method it doesn't find priv2Method method. Even though the builders object does show priv2Method as a property of it's prototype.

Hopefully someone could shed some light here.

Upvotes: 1

Views: 110

Answers (1)

mu is too short
mu is too short

Reputation: 434665

Your call function is not a private method, there is no such thing in JavaScript so there is no such thing in CoffeeScript.

A more accurate description of call would be:

a function that is only visible inside the builders class.

Defining call with => creates something the behaves like a private class method. Consider this:

class C
    p = => console.log(@)
    m: -> p()

c = new C
c.m()

If you look in the console you'll see that @ inside p is the class C itself, you'll see something in the console that looks like a function but that's all a CoffeeScript class is. That's why you see the var _this in the JavaScript. When CoffeeScript sees => and you're not defining a method, CoffeeScript uses the standard var _this = this trick to make sure the references come out right in the bound function.

Also note that your call is, more or less, a private class method so there is no builders instance and you can't call the instance method priv2Method without a builders instance.

Your privLedgeMethod method:

privLedgeMethod: =>
    call()

will work fine because call is a function (not a method), the function happens to be bound to the class but it is still just a function. Hence the lack of an @ prefix when you call(). If call was a proper class method:

@call: -> ...

then you'd call it as a class method in the usual way:

@constructor.call()

Here's a simple demo that might clarify things: http://jsfiddle.net/ambiguous/tQv4E/

Upvotes: 1

Related Questions