CoffeeScript与JavaScript代码对比

前言

最近在做服务端,项目是用CoffeeScript(一下简称CS)来写的,不由感慨,JS大法好。(数据库用的是mongodb…也是js系)

第一印象

CS提供了一个官网:http://coffee-script.org。官网的教程非常不错,很多知识点都讲得非常细,而且篇幅也不多。但是看里面的一些CS代码之后,发现对于刚刚接触CS的人来说,CS代码是居然如此难以阅读!!!我并不推荐为了少敲几下键盘,牺牲了代码的可读性。毕竟现在的IDE,已经有非常智能的补功能了。

不过实际操作下来,发现的确是可以少敲很多代码。 - -!

下面例举一些CS吊炸天的语法

  1. 循环递推
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    foods = ['broccoli', 'spinach', 'chocolate']
    eatTime = true
    alert food for food in foods when food isnt 'chocolate' if eatTime
    ###
    这表达式,简直逆天了
    if (eatTime) {
    for (_i = 0, _len = foods.length; _i < _len; _i++) {
    food = foods[_i];
    if (food !== 'chocolate') {
    alert(food);
    }
    }
    }
    ###
  2. ?符号
    1
    2
    3
    4
    5
    6
    7
    solipsism = true if mind? and not world? and flag
    ###
    翻译过来就是这样...太绕了。
    if ((typeof mind !== "undefined" && mind !== null) && (typeof world === "undefined" || world === null) && flag) {
    solipsism = true;
    }
    ###
  3. 遍历操作
  • 遍历数组:
    for item , idx in arr # idx from 0
  • 遍历对象属性
    for key , value of object
  1. 几乎所有的东西,都是表达式,这个很重要
    1
    2
    3
    4
    5
    6
    7
    8
    max = if 3 < 3 then 3 else 2
    # max = 3 < 3 ? 3 : 2;

    idx = 3
    x = while idx--
    "#{idx}"
    alert(x)
    ## 输出 210

写一些例子吧

  1. 原型上增加方法
    CS代码

    1
    2
    3
    4
    5
    6
    7
    8
    class Stu
    name : "";
    constructor: (@name) ->
    setName : (@name) ->
    setAge : (_age) ->\
    @age = _age
    Stu.x = 1 # 也就是TypeScript中的静态属性
    Stu::getName = -> @name # 原型方法,也就是TypeScript中的成员方法
  2. 继承

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    class Father
    name : "";
    constructor: (@name) -> alert("Father")
    showName : -> alert("showName #{@name}")

    class Son extends Father
    ###
    如果子类不写构造方法,则会调用父类的构造方法
    如果子类写了,则不会调用父类方法,除非显示调用。(其他方法的调用方式和这个一致)
    ###
    constructor :(_name) ->
    super("father name")
    alert("Son")
    @name = _name

    sonInstance = new Son("son name")
    sonInstance.showName()

do while 实现方式

1
2
3
4
isOk = false
loop
isOk = true
break if isOk

细节

  1. 数组

    1
    2
    数组(3..6),会包含最后一个数据
    通过三个点号的写法(3...6),不会包含最后一个数据
  2. switch语句

    1
    2
    3
    4
    5
    switch day
    when "x" then "xxx"
    when "y" then "y"
    when "a", "b" then "ab"
    else "default"
  3. 函数多返回值

    1
    2
    3
    4
    weatherReport = (location) ->
    # 发起一个 Ajax 请求获取天气...
    [location, 72, "Mostly Sunny"]
    [city, temp, forecast] = weatherReport "Berkeley, CA"
  4. 还有这个

    1
    healthy = 200 > cholesterol > 60
  5. 操作符

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    is  ===
    isnt !==
    not !
    and &&
    or ||
    true, yes, on true
    false, no, off false
    @, this this
    of in
    in no JS equivalent
    a ** b Math.pow(a, b)
    a // b Math.floor(a / b)
    a %% b (a % b + b) % b

坑,绝对的坑!

因为coffee是靠缩进来解析代码的,这导致即使是一个空格也会产生BUG。
比如下面这个问题,当时查了好半天。

1
2
3
4
5
6
idx= count * (page - 1) -1
### 这句话会被解析为
idx = count * (page - 1)(-1);
(page - 1)被解析为函数了
只要把"-1"改成"- 1"就好了
###

小结

看完官方的整个教程,其实可以发现,CoffeeScript和TypeScript是两种不同类型的JS语法变种,后者更倾向于把JS变为Java之类的语言,而本篇的CS,则是为了让JS代码,变得更加精简,但这也导致代码的可读性降低了不少(虽然熟悉了之后,这种情况可以减轻不少,但是我还是不怎么推荐)。

转载本站文章请注明作者(xtutu)和出处 xtutu