1

This JavaScript works great, because the JS runtime parses everything for declarations before running statements.

try {
    function Test() {
        this.speak = function() { alert('From Test!') }
    }
    test = new Test
    test.speak()
} catch (error) {
    alert(error);
}

try {
    secondtest = new SecondTest
    secondtest.speak()
    function SecondTest() {
        this.speak = function() { alert('From SecondTest!') }
    }
} catch (error) {
    alert(error)
}
// Alert: 'From Test!'
// Alert: 'From SecondTest!'

However, the corresponding CoffeeScript does not work when I create an instance of a class above its declaration:

try 
    class Test
        speak: -> alert 'From Test!'
    test = new Test
    test.speak()
catch error
    alert error

try
    secondtest = new SecondTest
    secondtest.speak()
    class SecondTest
        speak: -> alert 'From SecondTest!'
catch error
    alert error
// Alert: 'From Test!'
// Alert: 'TypeError: undefined is not a function'
Kerrick
  • 7,420
  • 8
  • 40
  • 45

2 Answers2

4

No.

This is just how coffeescript works, as was mentioned in a previous deleted answer. All coffeescript functions are declared using var in the transpiled javascript thus they are not subject to function hoisting, which makes the out-of-order use of constructor functions possible in javascript. I'm with Jeremy Ashkenas here in that function hoisting constitutes one of the "bad parts" of javascript and is completely unnecessary (see python, ruby, etc where referencing names declared further down the file is an error). To use your own words, yes "you will always have to declare classes before you use them", but I disagree that this is difficult. It's fine.

Community
  • 1
  • 1
Peter Lyons
  • 142,938
  • 30
  • 279
  • 274
2

In addition to what @PeterLyons said, let me refer you to the The Little Book on CoffeeScript that gives an explanation on why you're trying to do something bad:

The trouble is, hoisting behavior differs between browser; for example:

if (true) {
  function declaration() {
    return "first";
  }
} else {
  function declaration() {
    return "second";
  }
}
declaration();

In some browsers such as Firefox, declaration() will return "first", and in other browsers like Chrome it'll return "second", even though it looks like the else statement is never run.

Daniel Kaplan
  • 62,768
  • 50
  • 234
  • 356