CoffeeScript缺陷

没有任何疑问,CoffeeScript是一门优秀的编程语言,但是不管他再怎么优秀都有一些不尽如人意的地方。这里结合我使用这门语言几天的经验来说一下CoffeeScript的初体验一些缺陷

 


最大的问题:缺乏强有力的IDE

由于CoffeeScript是一门新生的语言,相当多的开发环境还没有完全的支持他。

  • 如果你使用Visual Studio编辑,你不得不建立一个.net网站工程才能在里面编辑CoffeeScript,否则你不能得到代码提示。
  • 如果你使用Notepad++编辑,你不会得到任何编码提示
  • 如果你使用eclipse进行编辑,目前的支持还是很有限的
  • http://fiddlesalad.com/coffeescript/ 这个在线IDE还是感觉很不错的,功能很强大,但是由于它只能在线使用,所以可能无法在没有网络的情况访问,另外它要求一定要联网,对于那些不开源的商业应用也是很大的挑战。

第二大问题:缩进来判断代码结束

可能有人比较喜欢用缩进来结束代码,但是我非常不喜欢,尤其是当代码非常长的时候。当你的IDE不支持智能缩进的时候这更是一件非常辛苦的事情

第三大问题:不完全的OOP特性

CoffeeScript支持OOP无疑是非常方便的,但是很不幸的是这个支持是非常有限的。在这里一个没有办法通过CoffeeScript的成员自动添加定义一个类里面的私有成员,你只能通过一些技巧来实现手动的添加私有成员。在CoffeeScript里面,这里的私有成员只能是私有的,还不能实现保护成员。

所以记住:CoffeeScript只是JavaScript

第四大问题:糟糕的函数参数表设计

在CoffeeScript调用一个有参数函数你可以省略掉参数表的括号,但是这并不意味着你可以省略掉所有的括号:在无参数的时候你必须加上括号。这样的方式可能带来一个团队项目里面编码习惯的混乱。

第五大问题:变量自动声明导致的拼写错误

变量生存周期自动管理缺失不错,但是,这引来了一个问题:你可能因为一些失误错误的拼写了某些变量名,这样,在你的IDE没有办法给你足够的提示的时候,你不得不花费大量的时间去检查这样一个低级的错误


不管怎样,CoffeeScript都是一款优秀的语言,去尝试一下都是很好的,但是如果要实际的应用还是要一些勇气的

 

CoffeeScript 像写诗一样写程序

昨天在编译ABPlayerHTML5的时候无意间发现了CoffeeScript这语言,以前虽然有过听说,但是都不屑的无视掉了这门语言。昨天在我看到这门语言的时候深深的被它吸引了,这种触动就和我第一次接触jQuery的时候一样,这给开发者的体验简直能用“感动”这个词来描述。

CoffeeScript是一种脚本语言没错,但是它还是需要编译的。它拥有一个javascript写的编译器用来把CoffeeScript编译到JavaScript。你可以在你的浏览器里面进行CoffeeScript的编译,但是更常见的做法是通过node.js来编译你的CoffeeScript。在node.js安装你的CoffeeScript是非常简单的一件事情:CoffeeScript已经可以直接通过npm获得你只需要下面一条指令就能获得最新稳定版的CoffeeScript

sudo npm install -g coffee-script

CoffeeScript里面你不需要特别的定义变量,一切变量的作用域都会自动的在最小的范围内。不像JavaScript,一切不声明var的变量都是全局变量。CoffeeScript会自动的声明变量。
# 赋值:
number   = 42
opposite = true

# 条件:
number = -42 if opposite

# 函数:
square = (x) -> x * x

# 数组:
list = [1, 2, 3, 4, 5]

# 对象:
math =
  root:   Math.sqrt
  square: square
  cube:   (x) -> x * square x

# Splats:
race = (winner, runners...) ->
  print winner, runners

# 存在性:
alert "I knew it!" if elvis?

# 数组 推导(comprehensions):
cubes = (math.cube num for num in list)

上面的这一段CoffeeScript编译之后就会变成下面的代码

var cubes, list, math, num, number, opposite, race, square,
  __slice = [].slice;

number = 42;

opposite = true;

if (opposite) {
  number = -42;
}

square = function(x) {
  return x * x;
};

list = [1, 2, 3, 4, 5];

math = {
  root: Math.sqrt,
  square: square,
  cube: function(x) {
    return x * square(x);
  }
};

race = function() {
  var runners, winner;
  winner = arguments[0], runners = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
  return print(winner, runners);
};

if (typeof elvis !== "undefined" && elvis !== null) {
  alert("I knew it!");
}

cubes = (function() {
  var _i, _len, _results;
  _results = [];
  for (_i = 0, _len = list.length; _i < _len; _i++) {
    num = list[_i];
    _results.push(math.cube(num));
  }
  return _results;
})();

CoffeeScript吸引人的特性除了这一点还有好多,比如CoffeeScript提供了类以及继承

class Animal
  constructor: (@name) ->

  move: (meters) ->
    alert @name + " moved #{meters}m."

class Snake extends Animal
  move: ->
    alert "Slithering..."
    super 5

class Horse extends Animal
  move: ->
    alert "Galloping..."
    super 45

sam = new Snake "Sammy the Python"
tom = new Horse "Tommy the Palomino"

sam.move()
tom.move()

编译之后的代码如下

var Animal, Horse, Snake, sam, tom,
  __hasProp = {}.hasOwnProperty,
  __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };

Animal = (function() {
  function Animal(name) {
    this.name = name;
  }

  Animal.prototype.move = function(meters) {
    return alert(this.name + (" moved " + meters + "m."));
  };

  return Animal;

})();

Snake = (function(_super) {
  __extends(Snake, _super);

  function Snake() {
    return Snake.__super__.constructor.apply(this, arguments);
  }

  Snake.prototype.move = function() {
    alert("Slithering...");
    return Snake.__super__.move.call(this, 5);
  };

  return Snake;

})(Animal);

Horse = (function(_super) {
  __extends(Horse, _super);

  function Horse() {
    return Horse.__super__.constructor.apply(this, arguments);
  }

  Horse.prototype.move = function() {
    alert("Galloping...");
    return Horse.__super__.move.call(this, 45);
  };

  return Horse;

})(Animal);

sam = new Snake("Sammy the Python");

tom = new Horse("Tommy the Palomino");

sam.move();

tom.move();

CoffeeScript的函数绑定功能也是非常的方便

Account = (customer, cart) ->
  @customer = customer
  @cart = cart

  $('.shopping_cart').bind 'click', (event) =>
    @customer.purchase @cart

编译之后的代码是这样的

var Account;

Account = function(customer, cart) {
  this.customer = customer;
  this.cart = cart;
  return $('.shopping_cart').bind('click', (function(_this) {
    return function(event) {
      return _this.customer.purchase(_this.cart);
    };
  })(this));
};

更多的资料可以参考 http://coffee-script.org/