JavaScript 如何优雅地将 CoffeeScript 写的 class 暴露给全局?

cassiuschen · 2015年05月26日 · 最后由 MrPasserby 回复于 2015年06月17日 · 3513 次阅读

感觉这是个会经常出现的场景: 用 CoffeeScript 写了一个 Class 来控制 UI,一如:

class Step
    constructor: ({selector: @selector, container: @container}) ->
        @self = $(@selector)
        @content = $(@container)
        @size = $("#{@selector}>.step").length
        @active = $("#{@selector} .active.step")
        return

    nextStep: (html) ->
        @active.removeClass("active").addClass("completed").next().addClass("active") 
        @__mountContent html
        return

    __clearContent: ->
        @content.html()

    __mountContent: (data) ->
        @__clearContent()
        @content.html data

在 Rails 中用 remote 更新 UI 的时候写到了形如

var step = new Step({
    selector: 'registStep',
    container: '#registContent'
});
step.nextStep("<%= j render partial: 'stuff/dashboard/set_college_form', locals: {colleges: College.all}%>");

调用 class 中的 function 来更新,结果就是 class 被 CoffeeScript 默认的匿名包给屏蔽,并没有暴露给全局。

在不更改 CoffeeScript 默认渲染方式的情况下,如何可以优雅地把这种 component 暴露给全局呢?

目前有一种方式比如写完 class 之后写: window.Step = Step,但是一点都不优雅……新建的时候居然要 var step = new window.Step(...) 新建的时候写 var step = new Step(...);倒是可以……

所以最终相对优雅的方法是 @rei@greatghoul 提出的用this来包 class 名称的做法: 如:

class @Step
    ........

新建的时候居然要 var step = new window.Step(...)

不用,直接 new Step()

#1 楼 @rei 就是因为之前直接写new Step()有问题,说找不到 Step 这个常量所以才意识到匿名包的问题……

#1 楼 @cassiuschen 挂到 window 之后就是全局了。(浏览器环境)

#1 楼 @rei 但依然还是不能找到Step这种常量……还得是window.Step……我不知道这么理解对不对,window 本身就是个 js 对象,和 hash 似的,往上写 window.Step = 也就只是类似 window[:Step] 赋值一样……所以调用的时候还是得带上 window?

#1 楼 @rei 恩应该是浏览器环境的问题……

coffee 官方文档推荐的就是挂到 window,如果要兼容 CommonJS 可以挂到 exports ? this,this 如果不用其它载入工具就是 window,然后 this 可以简写成 @,而且 class @Step 的写法也是可以的 ……看你喜欢哪种了,挂到 window 的方法没有问题。

不带 var 的都会暴露给 window,想不优雅都不行。

暴露给 window 妥妥的,不过可以想想如何优雅地暴露

#1 楼 @billy coffee 里不带 var……怎么写?

#1 楼 @billy coffee 不会。

@rei @cassiuschen 是的是的,好久都没有喝咖啡了,没概念了。

class @Step
 ...

这个确实有点囧 前两天 coffee 写 Meteor,Meteor 文档是要将 Model 暴露给全局,结果各种不能自理(也许我仍然没找到正确的姿势) 最后 Model 用 js 了事

不能暴露出去不就是因为有个闭包吗 coffee 闭包最后也是传了 this 的

@.Step = class Step
    constructor: ({selector: @selector, container: @container}) ->
        @self = $(@selector)
        @content = $(@container)
        @size = $("#{@selector}>.step").length
        @active = $("#{@selector} .active.step")
        return

    nextStep: (html) ->
        @active.removeClass("active").addClass("completed").next().addClass("active") 
        @__mountContent html
        return

    __clearContent: ->
        @content.html()

    __mountContent: (data) ->
        @__clearContent()
        @content.html data
console.log(Window.Step);  //undefined
console.log(Step);
//function Step(arg) {
//      this.selector = arg.selector, this.container = arg.container;
//      this.self = $(this.selector);
//      this.content = $(this.container);
//      this.size = $(this.selector + ">.step").length;
//      this.active = $(this.selector + " .active.step");
//      return;
//    }

#17 楼 @rei 囧 忘了这里的 this 其实就是 window 错误的就保留在上面吧

不过在不用闭包的情况下直接用 var 声明变量,似乎和window是一个意思吧

var b = '123'
// undefined
b === window.b
// true
需要 登录 后方可回复, 如果你还没有账号请 注册新账号