Working with CoffeeScript is a series of short blog posts about working with CoffeeScript every day and sharing the tips and tricks that we’ve learned.
When working with CoffeeScript you probably have noticed that, in some cases, classes may appear to be named _Class
when you inspect them in the Developer Tools. This usually happens when declaring a class as an object property or a when declaring an inner class. For example:
class TopClass
constructor: ->
@name = "TopClass"
instantiateInnerClass: ->
return new @InnerClass()
InnerClass: class
constructor: ->
@name = "InnerClass"
topClass = new TopClass()
innerClass = topClass.instantiateInnerClass()
# This will output: _Class {name: "InnerClass"}
console.log innerClass
This can be annoying when using the debugger to step through your code because the call site will appear as _Class
, which isn’t meaningful debugging information.
Let’s take a look at the compiled JavaScript:
var TopClass, innerClass, topClass;
TopClass = (function() {
function TopClass() {
this.name = "TopClass";
}
TopClass.prototype.instantiateInnerClass = function() {
return new this.InnerClass();
};
TopClass.prototype.InnerClass = (function() {
function _Class() {
this.name = "InnerClass";
}
return _Class;
})();
return TopClass;
})();
topClass = new TopClass();
innerClass = topClass.instantiateInnerClass();
console.log(innerClass);
Notice the _Class
declaration. This is the default name given to any class when the CoffeeScript compiler cannot infer a name for the class. To give the class a name, you must use the following syntax:
ClassName: class ClassName
constructor: ->
If we apply this technique to our previous example:
class TopClass
constructor: ->
@name = "TopClass"
instantiateInnerClass: ->
return new @InnerClass()
InnerClass: class InnerClass
constructor: ->
@name = "InnerClass"
topClass = new TopClass()
innerClass = topClass.instantiateInnerClass()
# This will output: InnerClass {name: "InnerClass"}
console.log innerClass
Which compiles to:
var TopClass, innerClass, topClass;
TopClass = (function() {
var InnerClass;
function TopClass() {
this.name = "TopClass";
}
TopClass.prototype.instantiateInnerClass = function() {
return new this.InnerClass();
};
TopClass.prototype.InnerClass = InnerClass = (function() {
function InnerClass() {
this.name = "InnerClass";
}
return InnerClass;
})();
return TopClass;
})();
topClass = new TopClass();
innerClass = topClass.instantiateInnerClass();
console.log(innerClass);
In conclusion, when declaring classes as object properties, always use the following syntax to preserve naming:
obj =
ClassName: class ClassName
constructor: ->
It’s more verbose, but gives more meaningful information while debugging.
Share: Y
blog comments powered by Disqus