V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
taoche
V2EX  ›  程序员

请教一些 CoffeeScript 的问题

  •  
  •   taoche · 2014-08-01 10:38:01 +08:00 · 4845 次点击
    这是一个创建于 3527 天前的主题,其中的信息可能已经有所发展或是发生改变。
    CoffeeScript这个语法糖,使用起来感觉挺不错,特别是写面向对象,class有了类的感觉。但是用于生产环境的时候发现有一些问题,请教一下大家。

    1: CoffeeScript可以写 函数声明吗? 根据CoffeeScript的文档,CoffeeScript只有函数表达式的写法。这种写法有执行上下文。调用必须在定义的下面,感觉不是很方便。

    2:CoffeeScript 会自动在函数体内 return最后一句。。为了不让它return,只能自己写一句return true 感觉很傻很浪费。
    31 条回复    2014-08-02 13:02:28 +08:00
    yangff
        1
    yangff  
       2014-08-01 10:43:03 +08:00 via Android
    你可以写一个0的。。
    taoche
        2
    taoche  
    OP
       2014-08-01 11:08:23 +08:00   ❤️ 1
    @yangff 这。。。
    datou552211
        3
    datou552211  
       2014-08-01 11:16:33 +08:00 via iPhone
    return挺好的啊,不仅返回值的时候需要它。还可以观察函数执行情况
    taoche
        4
    taoche  
    OP
       2014-08-01 11:46:27 +08:00   ❤️ 1
    @datou552211 自己忘记写return了 就容易出错
    7anshuai
        5
    7anshuai  
       2014-08-01 11:55:28 +08:00
    @taoche
    可以直接内嵌JS的函数声明代码
    abc()
    `function abc(){}`
    但是推荐用函数表达式
    orancho
        6
    orancho  
       2014-08-01 12:05:51 +08:00
    “自动在函数体内return最后一句”是从Ruby继承的
    taoche
        7
    taoche  
    OP
       2014-08-01 12:06:58 +08:00   ❤️ 1
    @orancho 这个不是说不好,而是和js的思想有点不一样。
    taoche
        8
    taoche  
    OP
       2014-08-01 12:09:52 +08:00   ❤️ 1
    @7anshuai 感谢,'' 确实是一个解决办法。
    用函数表达式,比较严谨。但是声明比较灵活。 经过这段时间的书写,感觉函数表达式可读性更强一些。
    和python 依赖模块 需要先import requirejs的amd模块也推荐的是先定义。
    lsj5031
        9
    lsj5031  
       2014-08-01 12:27:48 +08:00
    第一個問題沒怎麼看懂,我猜 do 是不是滿足要求?
    第二個問題如果不想返回值留個空 return 就好了呀,自動 return 出錯的場景暫時沒見過。
    linux 下用的 rime, 繁體見諒。
    taoche
        10
    taoche  
    OP
       2014-08-01 12:32:10 +08:00   ❤️ 1
    @lsj5031 感谢回复。 我试了一下do 并不是函数声明的方式。
    第二个问题,空return是可以在编译的时候被过滤。
    zythum
        11
    zythum  
       2014-08-01 12:32:20 +08:00
    @lsj5031
    lz的意思是
    coffee 只能是 var noop = function () {}
    lz需要 function noop () {}
    orancho
        12
    orancho  
       2014-08-01 12:34:22 +08:00
    @orancho coffee本来就是Ruby社区的产物,初版解释器都是Ruby写的。某个Ruby程序员写js写烦了然后就写出了Ruby。 历史原因。
    zythum
        13
    zythum  
       2014-08-01 12:34:44 +08:00
    朱一看来coffee 最大的问题是 t/97426, 对于不会js,不知道coffee编译规则的很容易出现这种看上去顾名思义的问题。其他感觉都不是问题。
    zythum
        14
    zythum  
       2014-08-01 12:35:31 +08:00
    抱歉 忘记加空格了 t/97426
    zythum
        15
    zythum  
       2014-08-01 12:36:03 +08:00
    http://www.v2ex.com/t/125564 ...难道我忘记站内url跳转规则了?
    mcfog
        16
    mcfog  
       2014-08-01 12:41:18 +08:00
    个人认为coffee最大的问题是局部变量和外层的变量不能同名

    不过包括楼主说那几个问题,在coffee的两个比较大的分支里都有解决方案

    https://github.com/satyr/coco
    https://github.com/gkz/LiveScript/
    lsj5031
        17
    lsj5031  
       2014-08-01 12:54:48 +08:00
    @zythum
    啊,謝謝。明白了……
    imcotton
        18
    imcotton  
       2014-08-01 12:55:27 +08:00
    声明绝对局部变量可以采用 IIFE 的方式

    a = 1
    b = 2

    do ({a, b} = {}) ->
    a = 3
    b = 4
    imcotton
        19
    imcotton  
       2014-08-01 12:56:04 +08:00
    a = 1
    b = 2

    do ({a, b} = {}) ->
    a = 3
    b = 4
    imcotton
        20
    imcotton  
       2014-08-01 13:00:07 +08:00
    自己脑补上面最后两行的缩进吧
    66450146
        21
    66450146  
       2014-08-01 13:36:27 +08:00
    alsotang
        22
    alsotang  
       2014-08-01 14:32:47 +08:00
    1. 不能
    2. 不是 return true 是 return
    yangzh
        23
    yangzh  
       2014-08-01 14:38:51 +08:00
    我有个疑问,第一个问题,定义函数的方式 coffee 这样做不是很自然很合理吗。。我从来都没有意识到这是一个问题咧
    taoche
        24
    taoche  
    OP
       2014-08-01 14:46:20 +08:00   ❤️ 1
    @zythum 感谢
    taoche
        25
    taoche  
    OP
       2014-08-01 14:46:30 +08:00   ❤️ 1
    @alsotang 抱歉 手误!
    taoche
        26
    taoche  
    OP
       2014-08-01 14:47:18 +08:00   ❤️ 1
    @yangzh 这种写法有执行上下文。调用必须在定义的下面。
    没说不合理 只是不灵活
    zythum
        27
    zythum  
       2014-08-01 19:04:23 +08:00
    @66450146 谢谢 原来要先 / 的
    ant_sz
        28
    ant_sz  
       2014-08-01 23:16:33 +08:00
    coffeescript 强制你使用函数表达式的写法是为了避免 Javascript 函数声明的作用域bug。你应该接受这种写法,而且在以后写 Javascript 的时候也尽量采用这种写法。

    所谓作用域的bug,简单就是

    if (true) {
    function doSomething() { alert('A'); }
    } else {
    function doSomething() { alert('B'); }
    }

    doSomething()

    上述程序看似应该 alert 'A' 实际上将总是 alert 'B'
    taoche
        29
    taoche  
    OP
       2014-08-01 23:30:13 +08:00
    @ant_sz 这个不能算是作用域bug吧。 因为js没有块级作用域。 if else内也就没有作用域。根据 Js的预解析机制,后面的函数声明会覆盖前面的。
    ant_sz
        30
    ant_sz  
       2014-08-02 10:34:07 +08:00
    @taoche 是不是bug有点争议,虽然现代浏览器对这个有一定的优化,但是使用赋值式的函数声明还是有最好的兼容性。因此尽可能采用这种方式比较好。

    另外,貌似在这种coffeescript为了解决调用需要在声明之后的问题,在编译的时候会首先将所有作用域内的变量都声明下,譬如

    ```
    a = () -> console.log 'a'
    b = () -> console.log 'b'
    ```

    会被编译成

    ```
    (function() {
    var a, b; // 这里预声明了所有变量k

    a = function() {
    return console.log('a');
    };

    b = function() {
    return console.log('b');
    };

    }).call(this);
    ```

    所以在同一个作用域下面声明的函数之间是可以相互调用的。这个已经是比较符合预期的效果了。我实在看不出还有使用声明式的必要。
    taoche
        31
    taoche  
    OP
       2014-08-02 13:02:28 +08:00
    @ant_sz 明白了 感谢回答!
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3487 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 41ms · UTC 11:00 · PVG 19:00 · LAX 04:00 · JFK 07:00
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.