coffeescript中的名称空间
coffeescript中是否有对名称空间的内在支持coffeescript中的名称空间,coffeescript,Coffeescript,coffeescript中是否有对名称空间的内在支持 适当的名称空间似乎是coffeescript真正能提供帮助的东西,尽管我似乎找不到任何证据表明有人支持这一点。来自wiki上关于名称空间的部分: #代码: # 名称空间=(目标、名称、块)-> [目标、名称、块]=[(如果导出类型不是“未定义”,则导出其他窗口)、参数…]如果arguments.length
适当的名称空间似乎是coffeescript真正能提供帮助的东西,尽管我似乎找不到任何证据表明有人支持这一点。来自wiki上关于名称空间的部分:
#代码:
#
名称空间=(目标、名称、块)->
[目标、名称、块]=[(如果导出类型不是“未定义”,则导出其他窗口)、参数…]如果arguments.length<3
顶部=目标
target=target[item]或={}用于name.split.'中的项
顶住目标
#用法:
#
名称空间“Hello.World”(导出)->
#“exports”是附加命名空间成员的位置
exports.hi=->console.log“hi World!”
名称空间“Say.Hello”,(导出,顶部)->
#'top'是对主命名空间的引用
exports.fn=->top.Hello.World.hi()
Say.Hello.fn()打印“嗨,世界!”
我更喜欢将此模式用于“名称空间”。它实际上不是一个名称空间,而是一个对象树,但它完成了以下任务:
在应用程序启动的某个地方,您可以根据您的环境全局定义名称空间(将窗口
替换为导出
或全局
)
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
在类自身的“名称空间”(闭合函数)和全局名称空间中引用该类非常简单的一种方法是立即分配它。例如:
# 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
。如果您只想在测试命名空间中使用它,则可以进一步简化:
window.Test or= {}
# Create only in the namespace
class window.Test.MyClass
constructor: (@a) ->
你一定要去看看咖啡烤面包机:
它附带了一个打包系统,启用该系统后,将使用文件夹的层次结构作为类的命名空间声明(如果需要),然后可以从多个文件扩展类,执行导入和子操作,例如:
#<< another/package/myclass
class SomeClass extends another.package.MyClass
还有一个单独编译文件的调试选项,以简化调试过程和其他有用的功能
希望它能有所帮助。因为我也在忙着学习构造文件的最佳方法,并将coffeescript与主干和cake结合使用,所以我创建了一个用于保存它作为我自己的参考,也许它也会帮助你处理cake和一些基本的事情。All.js(带有cake编译文件)位于www文件夹中,这样您就可以在浏览器中打开它们,并且所有源文件(蛋糕配置除外)都位于src文件夹中。在本例中,所有.coffee文件都被编译并合并到一个output.js文件中,然后包含在html中
根据StackOverflow上的一些答案,我创建了一个小的util.coffee文件(在src文件夹中),它向代码的其余部分公开“名称空间”。我强烈建议使用requirejs.org或类似的经过战斗测试的模块加载程序。 特别是当你想异步加载的时候 如果您忽略了这一点,那么使用自己的名称空间/模块方案是非常困难的
简单、简单和天真的方法以下是我的个人实现: 如何在浏览器中使用:
namespace Foo:SubPackage1:SubPackage2:
class Bar extends Baz
#[...]
如何在CommonJS环境中使用:
require './path/to/this/file' # once
namespace Foo:SubPackage1:SubPackage2:
class Bar extends Baz
#[...]
请注意,可以编写:
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);
您有自动关闭的文件,这还不够吗?您必须详细说明“名称空间”的含义这是一个模棱两可的术语。我不会说这是CoffeeScript中流行的模式。人们通常只直接编写
exports.foo=bar
。请注意,您不必在这里使用window.App.Models
。只需App.Models?={}
可以。正确。我喜欢引用窗口。
在我的作业中,为了明确我的意思是做一个全局作业。对我来说,这只是一个编码风格的东西。我喜欢这个选项,它很好,很干净,很适合咖啡脚本语法。+1’我也非常喜欢这个解决方案,但IntelliJ的想法有一个换行符每次之后“:”自动格式化CoffeeScript代码时,该代码会断开文件:(在大多数压缩库下会断开(例如,您的缩小版本将无法工作)。命名空间名称下的类会损坏。这里的一个关键问题是window。没有它,我的编译器会出错。
class MyObject.MyClass
constructor: () ->
initializeStuff()
myfunction: () ->
doStuff()
(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);