defining classes for outer scope in CoffeScript

2019-07-25 15:45发布

问题:

This is a follow up to my previous question Javascript: ReferenceError: MyClass is not defined.

A .coffee file with this converted to .js will create a MyClass available only inside its scope.

class MyClass
    name: (name) -> 

Is there a way in CoffeScript to make the class available to the outer scope? I should be able to <script src.. the file on a HTML page and instantiate the class from the console.

回答1:

You'll "pollute the global scope" no matter how you do it. It's just a matter of how you do it.

The @ symbol in CoffeeScript is used to mean "this scope". So you can even use it on a Class definition. The result on a class declaration is that the class is defined in the scope of the window object (unless there are some other circumstances, but that's not likely in what you're describing here).

class @CustomClassName
    constructor: -> 
        # constructor stuff goes down...

However, I prefer to do this with a namespace, personally. Think about google.maps.Map or if you've ever written Actionscript 3: flash.display.MovieClip.

At the top of your CoffeeScript file put something along the lines of this:

window.customnamespace = window.customnamespace || {}

Now when you create your class, you can say:

class customnamespace.ClassName
    constructor: (container) ->
        # set the container
        @container = container
        # etc...

class customnamespace.OtherClassName
    constructor: ->
        # Another class...

In your document.ready (if you're using jQuery) you'll globally have access to that namespace and all its classes.

Example:

$(document).ready(function(e) {
    var c = new customnamespace.ClassName($('#container'));

    var other = new customnamespace.OtherClassName();

Make sense?



回答2:

This stackoverflow gives a very comprehensive overview of creating global objects with coffeescript with some very good examples included.

For this example the coffeescript:

window.MyClass = class MyClass
    name: (name) -> 

Will compile to:

var MyClass;

window.MyClass = MyClass = (function() {

  function MyClass() {}

  MyClass.prototype.name = function(name) {};

  return MyClass;

})();

Which will give the same behaviour as the answer to your previous question.