V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
zythum
V2EX  ›  Node.js

写coffee的同学你们知道这两个的区别么?

  •  1
     
  •   zythum · 2014-01-17 18:28:52 +08:00 · 7503 次点击
    这是一个创建于 3744 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我想要的意图是这样


    话说coffee是这样


    话说上下两种的区别是什么呢?

    话说今天手贱想看看coffee能把js精简到怎么样子。
    话说这个大家项目过程中都遇到过么

    话说我想要声明他是局部变量该怎么办呢?
    人为约定局部变量用 _ 开头?, 还是声明他作为函数的参数?

    注: 刚用coffee 2小时发现的问题。求用了2个月的同学指导。
    42 条回复    1970-01-01 08:00:00 +08:00
    panlilu
        1
    panlilu  
       2014-01-17 18:48:10 +08:00
    coffee 会自动在变量第一次出现时加上var,详细的可以在try coffee script里面敲两段代码观察生成的代码的不同之处。
    不用特地的声明是局部变量,只要这个变量名没在外面一层出现过就默认是局部的。
    zythum
        2
    zythum  
    OP
       2014-01-17 18:52:01 +08:00   ❤️ 1
    @panlilu 但是问题就是我不知道是不是外面出现过, 比如一个代码1000多行的。但是出现过了就不var...

    别说一个代码不用改1000多行.. 举个例子.
    zythum
        3
    zythum  
    OP
       2014-01-17 18:54:21 +08:00
    @panlilu 刚才体验了下。 ()-> 确实方便,少打字符。 语法糖确实用着不错。

    但是 朱一默认是想这js该怎么写。然后翻译成coffee是怎么样子的。就和当初学英语一样。
    zythum
        4
    zythum  
    OP
       2014-01-17 18:55:15 +08:00
    @Livid 自动标签取很准。这次的关键词确实是局部变量
    Mutoo
        5
    Mutoo  
       2014-01-17 19:02:11 +08:00
    @zythum 出现过的变量名有代码提示。

    或者试用 @ 修饰变量,相当于用 this

    p.s. 我不是用coffeescript 2个月,而是2个月前用过 coffeescript
    guangwong
        6
    guangwong  
       2014-01-17 19:05:19 +08:00
    卤煮你蛋疼不
    anjianshi
        7
    anjianshi  
       2014-01-17 19:12:51 +08:00
    一个勉强的解决的办法:
    value = 1
    fn = ->
    `var value` # 通过这句强制创建一个局部变量
    value = 2
    不过这样非常麻烦

    除此之外基本无解了,网上也有不少人提到这个问题,我估计 coffee 以后会改进
    目前就少用全局变量,多利用命名空间吧
    写了一段时间的 coffee 代码,比较长的也有,还没碰到关于它的问题
    anjianshi
        8
    anjianshi  
       2014-01-17 19:14:45 +08:00
    HaEx
        9
    HaEx  
       2014-01-17 19:18:53 +08:00
    qiukun
        10
    qiukun  
       2014-01-17 19:24:02 +08:00
    ((local var) ->gao)() 虽然官方说不能 shadow ,其实是可以的,大意就是通过闭包。
    zythum
        11
    zythum  
    OP
       2014-01-17 22:58:10 +08:00
    @Mutoo 不能用this, 不管是面向类,还是函数都不对。
    就比如
    function a(){this.a=5}; a(); window.a === 5;

    @anjianshi 这还不如用 _ 约素 或者 用参数做var 来得靠谱,比如 function(a,b, /*我是局部变量*/c) { c = 5}

    @qiukun 这个和用参数来代替var 是一个道理把

    @Mutoo 这个是很重要的问题。 因为如果想大规模使用的话是不能避免的。这种运行时的又是很隐性的问题是最要命的。万一出个这个方面的bug。都不知道怎么死的。bug一查就是半天过去了。
    Mutoo
        12
    Mutoo  
       2014-01-17 23:40:12 +08:00
    @zythum 看过几个coffeescript的项目,基本都靠测试框架来保证正确性。
    qiukun
        13
    qiukun  
       2014-01-18 00:08:34 +08:00
    @zythum 是一个道理,SO 有这个问题的
    yyfearth
        14
    yyfearth  
       2014-01-18 00:29:37 +08:00
    @zythum 隐形声明变量的语言也有不少 coffee 只是其中之一,如果你模块化或者OOP做的足够好,加上使用 Promise,那么 function 就不会也不应该嵌套太深。只要函数不嵌套太深,那么变量的 scope 控制也相对容易。
    另外对于 this 的控制 coffee 提供 -> => 就很不错。
    我用 coffee 主要是 OOP 比较方便,另外就是语法和糖比较适合我(喜欢 Ruby 语法)
    如果你仅仅是想用 coffee 里面的语法糖方便编码,那么还不如用新版本的 JS
    貌似 最新的 ECMAScript 就是 Harmony 解决了很多 JS 的坑(比如用 let 代替 var),而且把 coffee 很多特点吸纳过去了,比如 =>
    另外 class 什么的也都有了,还有强大的 generator 和 yield。
    zythum
        15
    zythum  
    OP
       2014-01-18 01:14:10 +08:00
    @yyfearth 好久不见。
    今天有仔细看了coffee。因为正好看到 松本行弘的书,松本便是coffee很有前途。
    这次只是对coffee的只是普及. Harmony 增加了不少语法糖,甚至把promise都加进去了。话=>的处理为什么是用_this = this来作为一个外部变量处理。不用func.bind(this)来转换this呢?

    话说这个不是嵌套太深的问题。只要是用函数。有类就会有这个问题, 特别是多人开发的时候。只是怎么去规避。举个例子
    http://gist.github.com/zythum/8477316

    这个例子是不是很简单又有普遍性。
    zythum
        16
    zythum  
    OP
       2014-01-18 01:31:52 +08:00
    发现一个呵呵的地方需要注意。
    因为函数默认return 最后一个表达式的值。所以如果需要一些函数返回值有特殊意义的。比如浏览器事件的回调函数。renturn fasle会阻止浏览器默认行为,那也会呵呵的。

    http://gist.github.com/zythum/8477617
    yyfearth
        17
    yyfearth  
       2014-01-18 01:45:07 +08:00
    @zythum return 也是我一个很头疼的地方 所以我基本上都 手动加 return 在最后面
    yyfearth
        18
    yyfearth  
       2014-01-18 02:06:59 +08:00
    @zythum function 后面如果不return任何东西我就手动加return,如果是method,最后都加个this
    yyfearth
        19
    yyfearth  
       2014-01-18 02:09:37 +08:00
    @zythum 应该是兼容性考虑,他们之前有那个branch,但是一直没动
    breeswish
        20
    breeswish  
       2014-01-18 09:06:10 +08:00
    @zythum ^^ 朱一也来Coffee的坑了哈~
    一开始也是觉得,写Coffee要想着怎么写,写起来特别慢,还要经常翻手册
    不过熟悉以后就写起来快多了,会写的很顺手的

    另外提醒一个坑,在coffee里的“全局”变量不在全局里(特指web下),因为最后外面会被闭包一下,所以必须要用window.来声明一个全局变量~
    zythum
        21
    zythum  
    OP
       2014-01-18 09:13:48 +08:00
    @breeswish

    (function(){ //所有代码在这里 }).call(this)

    这个刚开始就看到了。 谢谢提醒。
    其实不用window也是可以的。在最外面@ === window。所以@global也是全局的。
    skydiver
        22
    skydiver  
       2014-01-18 09:32:51 +08:00 via Android
    为啥我看到的帖子里是两块空白看不到代码?
    kingwkb
        23
    kingwkb  
       2014-01-18 09:53:40 +08:00
    @Livid 我也是看不到代码
    yayy
        24
    yayy  
       2014-01-18 12:57:28 +08:00
    @skydiver @kingwkb 因为传输 gist 的时候没走https,被 block 了。
    reducm
        25
    reducm  
       2014-01-18 13:04:41 +08:00
    @skydiver
    @kingwkb

    goagent设了github白名单吧, 关了直接可看。

    工作中用了一年多的coffee,倒从没遇到这个问题。的确要注意这种情况,全局函数还是加个window比较好点,感谢楼主提出。
    anjianshi
        26
    anjianshi  
       2014-01-18 16:37:15 +08:00   ❤️ 1
    @breeswish 编译的时候加个 --bare 参数就是"真"全局变量了
    miniwade514
        27
    miniwade514  
       2014-01-21 09:39:38 +08:00
    为何要用 call 和 apply 呢?为什么不直接 b = arguments.slice( 1 ); 和 sun( [ b, b[ 0 ] += a ][ 0 ] ); 呢?
    zythum
        28
    zythum  
    OP
       2014-01-21 10:25:57 +08:00   ❤️ 1
    @miniwade514

    1. 'slice' in arguments === false arguments并不是数组,是个类数组,没有slice方法的。所以需要借调用数组slice方法
    这里写作:
    [].slice.call(arguments, 1)
    [].slice.apply(arguments, [1])
    Array.prototype.slice.call(arguments, 1)
    Array.prototype.slice.apply(arguments, [1])
    都是可以的。

    2. 关于callee.apply: 习惯了在函数里面调用自身的时候不使用函数名。 因为以后如果要改函数名或者用到其他地方都要做相应的修改。这个仁者见仁智者见智把。
    zythum
        29
    zythum  
    OP
       2014-01-21 10:29:40 +08:00   ❤️ 1
    @miniwade514 还有就是使用arguments.callee.apply(this, [b, b[0] += a][0])可以保证递归的过程中this一致。虽然这个功能并不需要保证这个。
    miniwade514
        30
    miniwade514  
       2014-01-21 10:39:56 +08:00
    @zythum 一下涨了好多姿势!多谢 :D
    zythum
        31
    zythum  
    OP
       2014-01-21 10:40:00 +08:00
    当然我上面只是举个例子。
    sum函数科学的写法应该是这样

    http://gist.github.com/zythum/8533518

    当然需要ECMAScrip 5 标准。

    这样是不是发现coffee真的能少敲很多字。可以保护键盘哦。
    zythum
        32
    zythum  
    OP
       2014-01-21 10:46:49 +08:00
    @yyfearth 或者为什么折腾完coffee之后朱一开始不自觉得看ruby了怎么破...

    不是说要的要折腾oc的啊...话说oc完全看不进去啊怎么破...

    要是app可以拿ruby或者js写就好了5555 (不要跟我说node-webkit或者大HTML5做Web app。已经被web app坑惨了)
    yyfearth
        33
    yyfearth  
       2014-01-21 11:12:16 +08:00
    @zythum 在 strict mode 下面,裸 function 里面 this 不会是 window,另外 coffee 编译时候会自己在最外面加上一个 (function(){ ..... })()
    学习ruby没啥不好啊,ruby on rails 挺不错的,可以学习一下,以后说不定还会用到
    ObjC 我一直想碰,一直下不了手,原因有二:语法接受不了,那么一大堆的 [] 看到我头疼(习惯了C++/Java),另外就是如果写iOS,不越狱还没发真机用($99一年太贵了,必须找冤大头买单),想到就没兴趣了
    你说web app坑,我觉得怎么样都是坑,哪里有不坑的东西,只是看那个坑跳着舒服而已。
    yyfearth
        34
    yyfearth  
       2014-01-21 11:14:50 +08:00
    @zythum 记错了 外面用了 call this 就是window了
    zythum
        35
    zythum  
    OP
       2014-01-21 11:22:53 +08:00
    @yyfearth 不是window也没事。只要这次的this和下次的this一样就可以了。

    我发现ruby, func[这里不能有空格](1,2,3)

    $99 就500块么。折合一块五一天。还是可以接受的。虽然我也没买...
    yyfearth
        36
    yyfearth  
       2014-01-21 11:25:34 +08:00
    @zythum 另外就是JS的 this scope 真的很烦,所以用了coffee之后基本上全部都用 => 如果function在 method 内部,在用method的时候全部都 .bind(@)
    我用coffee的时候都注意完全不用全局变量,实在需要的用XXX = window.XXX 然后用XXX.xxx,最近用了require.JS 所以window基本上就不用了,需要的话在最后面 return 作为 export
    另外我记得 argument.callee 已经不能用了啊
    yyfearth
        37
    yyfearth  
       2014-01-21 11:29:22 +08:00
    @zythum 这个99刀可以有冤大头公司出就不想自己出啊
    coffee 里面 func(a,b) 和 func (a,b) 在语法层上也是不一样的,后者相当于 func((a,b))
    func(a,b).chain(...) 写成 func (a,b).chain(...) 就变成bug了
    zythum
        38
    zythum  
    OP
       2014-01-21 11:34:23 +08:00
    @yyfearth 你还是活在coffee里面把...

    污染window的尽量不要干。 bind我觉得是非常好的处理方式。给程序员足够的自由。不过是ES 5标准的。当然也是个语法糖。就是
    function bind(fn, context){ return fn.apply(context, arguments) }

    我还是觉得外面写个 var that = this 是很傻的解决方式。
    zythum
        39
    zythum  
    OP
       2014-01-21 11:35:46 +08:00
    @yyfearth 不是说了。没习惯么。
    zythum
        40
    zythum  
    OP
       2014-01-21 11:37:23 +08:00
    错了。 还要包个func
    function bind(fn, context){ return function () { fn.apply(context, arguments) }}

    @yyfearth
    yyfearth
        41
    yyfearth  
       2014-01-21 11:41:47 +08:00
    @zythum bind 的 polyfill 很简单,而且没什么功能性的问题
    另外就是EMACScript 6 也打算要加入 => 来保留 this
    讨厌的就是 coffee 好久没有更新了,本来打算新年release新版本,结果由于paper work太对,大大们实在不愿意动手
    还有就是需要加入generator的支持已经yield关键字,也需要等一段时间

    PS 用coffee太久,都没有加 ; 的习惯了,还好有IDE提醒
    runawaygo
        42
    runawaygo  
       2014-01-21 13:25:11 +08:00
    10+人的团队写了两年的coffeescript,Web前端,nodejs后端,App采用的是Titanium技术,所以也全都使用coffeescript,虽然js是函数第一型的语言,但是工程中类型化更加利于维护,所以无耻的使用coffeescript类型系统。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5202 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 48ms · UTC 07:34 · PVG 15:34 · LAX 00:34 · JFK 03:34
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.