在coffeescript中命名空间

时间:2011-11-11 07:40:32

标签: coffeescript

coffeescript中是否有对命名空间的内在支持?

充足的命名空间似乎是coffeescript可以真正帮助的东西,虽然我似乎无法找到任何暗示有支持的东西。

8 个答案:

答案 0 :(得分:35)

我更喜欢将此模式用于“命名空间”。它不是一个真正的命名空间,而是一个对象树,但它完成了这项工作:

在应用启动的某个地方,您可以全局定义命名空间(根据您的环境将window替换为exportsglobal

window.App =
  Models: {}
  Collections: {}
  Views: {}

然后,当你想要声明类时,你可以这样做:

class App.Models.MyModel
  # The class is namespaced in App.Models

当你想引用它时:

myModel = new App.Models.MyModel()

如果您不喜欢定义名称空间的全局方式,可以在课前进行:

window.App.Models ?= {} # Create the "namespace" if Models does not already exist.
class App.Models.MyModel

答案 1 :(得分:29)

一种简单的方法,可以在它自己的“命名空间”(闭合函数)和全局命名空间中引用类,以便立即分配它。例如:

# Define namespace unless it already exists
window.Test or= {}

# Create a class in the namespace and locally
window.Test.MyClass = class MyClass
  constructor: (@a) ->

# Alerts 3
alert new Test.MyClass(1).a + new MyClass(2).a

如您所见,现在您可以在文件中将其称为MyClass,但如果您需要它,则可以将其作为Test.MyClass使用。如果您只想在Test命名空间中使用它,您可以进一步简化它:

window.Test or= {}

# Create only in the namespace
class window.Test.MyClass
  constructor: (@a) ->

答案 2 :(得分:10)

这是我的个人实施:

https://github.com/MaksJS/Namespace-in-CoffeeScript

如何在浏览器中使用:

namespace Foo:SubPackage1:SubPackage2:
  class Bar extends Baz
    #[...]

如何在CommonJS环境中使用:

require './path/to/this/file' # once

namespace Foo:SubPackage1:SubPackage2:
  class Bar extends Baz
    #[...]

答案 3 :(得分:5)

来自wiki上的命名空间部分:https://github.com/jashkenas/coffee-script/wiki/FAQ

# Code:
#
namespace = (target, name, block) ->
  [target, name, block] = [(if typeof exports isnt 'undefined' then exports else window), arguments...] if arguments.length < 3
  top    = target
  target = target[item] or= {} for item in name.split '.'
  block target, top

# Usage:
#
namespace 'Hello.World', (exports) ->
  # `exports` is where you attach namespace members
  exports.hi = -> console.log 'Hi World!'

namespace 'Say.Hello', (exports, top) ->
  # `top` is a reference to the main namespace
  exports.fn = -> top.Hello.World.hi()

Say.Hello.fn()  # prints 'Hi World!'

答案 4 :(得分:3)

你必须真正查看CoffeeToaster:
https://github.com/serpentem/coffee-toaster

它带有一个打包系统,如果你愿意,它会在你启用时使用你的文件夹的层次结构作为你的类的命名空间声明,然后你可以从多个文件扩展类,执行导入和子,例如:

#<< another/package/myclass
class SomeClass extends another.package.MyClass

构建配置非常极简和简单,显而易见:

# => SRC FOLDER
toast 'src_folder'
    # => VENDORS (optional)
    # vendors: ['vendors/x.js', 'vendors/y.js', ... ]

    # => OPTIONS (optional, default values listed)
    # bare: false
    # packaging: true
    # expose: ''
    # minify: false

    # => HTTPFOLDER (optional), RELEASE / DEBUG (required)
    httpfolder: 'js'
    release: 'www/js/app.js'
    debug: 'www/js/app-debug.js'

还有一个调试选项可以单独编译文件,以简化调试过程和其他有用的功能。

希望它有所帮助。

答案 5 :(得分:1)

请注意,可以写:

class MyObject.MyClass
    constructor: () ->
        initializeStuff()
    myfunction: () ->
        doStuff()

如果你声明了一个对象/ ns MyObject。

虽然我们在这里,但这是我对jquery-ns函数的实现:

(function($) {
    $.namespace = function(namespace, initVal) {
        var nsParts = namespace.split("."),
            nsPart = nsParts.shift(),
            parent = window[nsPart] = window[nsPart] || {},
            myGlobal = parent;
        while(nsPart = nsParts.shift()) {
            parent = parent[nsPart] = parent[nsPart] || {};
        }
        return myGlobal;
    }
})(jQuery);

答案 6 :(得分:0)

由于我也忙着学习构建文件的最佳方法,并将coffeescript与backbone和cake结合使用,我创建了一个small project on github来保留它作为我自己的参考,也许它会有所帮助你也围着蛋糕和一些基本的东西。所有.js(带有蛋糕编译文件)都在 www 文件夹中,以便您可以在浏览器中打开它们,所有源文件(蛋糕配置除外)都在 src 文件夹中。在此示例中,所有.coffee文件都在一个输出.js文件中进行编译和组合,然后将其包含在html中。

根据StackOverflow上的一些答案,我创建了一个小的util.coffee文件(在src文件夹中),它将“命名空间”暴露给其​​余的代码。

答案 7 :(得分:0)

我强烈建议使用requirejs.org或类似的经过测试的模块加载器。 特别是如果你想异步加载东西。

如果忽视,滚动自己的命名空间/模块方案真的很难 简单,容易和天真的方法