使用CoffeeScrip优美方式编写javascript代码(2)

列表解析是CoffeeScript的世界里的重要一员。它改变了循环的思路。CoffeeScript没有提供像JavaScript那样的for循环结构,而是统统转化为列表解析。一个常规的JavaScript for循环,像下面这样:

food_list = ['toast', 'cheese', 'wine']; for (i = 0, len = food_list.length; i < len; i++) { food = food_list[i]; eat(food); }

用CoffeeScript实现就是:

food_list = ['toast', 'cheese', 'wine']
eat food for food in food_list #做个小补充,for循环的单条语句的写法

单单是上面的例子不足以显示列表解析的强大(却看到它的简洁了)。在继续这个话题之前,我觉得我有必要补充一下另一个涉及到CoffeeScript理念的东西了:一切皆是表达式。

在CoffeeScript世界里,一切语句都是表达式语句,都会返回一个值。函数调用默认会返回最后一条语句的值。if条件结构也会返回值,其返回的是执行的最后一条语句的值。循环结构有些不同,其会将每次循环的结果都保存在一个数组里,作为此循环结构的值。例如下面代码的list结果就是[5, 4, 3, 2, 1]。

num = 6 list = while num -= 1 num

回到列表解析的主题。与while一样,for结构也是一种循环的表达,其结果也是一个数组。回到先前的例子,下面的小代码的list结果就是['t', 'c', 'w']。

food_list = ['toast', 'cheese', 'wine'] list = (food[0] for food in food_list)

我们已经看到for循环的each形式

eat food for food in food_list

以及它的map形式

(food[0] for food in food_list)

下面给出它的filter形式

(food for food in food_list when food is 'wine')

列表解析的特色的地方在于它改变了我们组织循环的方式和解析数组的模式。这是一种声明式的编程方法,告诉程序你想要什么而不去关心构建的过程。

类的支持

类是CoffeeScript对JavaScript的一个很重要的补充。JavaScript的原型功能很强大,写法上又恨别扭。正确地设置原型链以实现继承关系也是个很大的挑战。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()

从实现上来说,CoffeeScript的类与JavaScript的构造函数和原型链那一套并无二致。所以,理解原型机制也是理解CoffeeScript类的基础。

关于JavaScript的糟粕

CoffeeScript的另一个目标是从语法层面上直接消除JavaScript的被人诟病的一些糟粕部分。前面已经说过关于分号的部分。关于var声明的部分。分号的机制暂且不去例会,总之CoffeeScript不用再去写分号了。

在JavaScript当中,最为人诟病的糟粕部分有两处,因为它们使用的情况最多而且容易出错。

全局变量

相等比较

全局变量

JavaScript的作用域规则很复杂,涉及到var声明机制和变量提升。在JavaScript里,构造一个全局变量是很容易的,有三种方式:

在全局的环境里用var声明

var name = 'name';

在函数内用省略var的方式定义

function foo() { name = 'name'; }

绑定到window的属性

window.name = 'name';

其中第1种和第2种方式是最常见的错误用法。首先不推荐直接在全局环境中编码,而是应该用一个匿名函数包裹起来,将程序的作用域限制在这个匿名函数中。第二种用法完完全全就是忘记了var声明。而我在实际的JavaScript编码中,忘记var声明是常有的事(就像经常忘记行末补上分号一样)。

而在CoffeeScript里面就完全没有这种担心了。首先,编译后的JavaScript代码不会暴露在全局环境里,所有的代码都是自动包裹在一个匿名函数(function(){ ... })();内。然后,所有的变量都会自动加上var声明。这就使得不小心污染全局的情况很难发生,除非使用赋值到window上。

相等比较

我们都知道JavaScript有两种比较运算符:==和===。我们也知道==在使用的过程中会很坑,所以平时都宁愿多打一个字符而使用===。CoffeeScript的只有一种比较运算符==,而它会编译成JavaScript的===,从而很好地避过了这道坑。

是否该使用CoffeeScript

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wgzpwf.html