CoffeeScript

CoffeeScript_第1张图片

今天和大家介绍一个有趣的东西....

介绍

CoffeeScript 是一门编译到 JavaScript 的小巧语言. 在 Java 般笨拙的外表下, JavaScript 其实有着一颗华丽的心脏. CoffeeScript 尝试用简洁的方式展示 JavaScript 优秀的部分.
CoffeeScript 是一门简洁的,构架于JavaScript之上的预处理器语言,可以静态编译成JavaScript,语法主要受ruby和python影响。

优点&&安装

  • 更少,更紧凑,和更清晰的代码
  • 通过规避和改变对JavaScript中不良部分的使用,只留下精华,让代码减少出错率,更容易维护
  • 在很多常用模式的实现上采用了JavaScript中的最佳实践
  • CoffeeScript生成的JavaScript代码都可以完全通过JSLint的检测

安装
最简单的安装和测试CoffeeScript的方法,是使用node.js的npm安装,然后使用命令行脚本实时编译

npm install -g coffee-script
coffee -w --output lib --compile src

什么情况下不推荐使用CoffeeScript?

CoffeeScript不是JavaScript的超集,也不是完全替代品,不应该在不会JavaScript的情况下使用CoffeeScript工作。

CoffeeScript是一种需要预编译的语言,不能在运行时(Runtime)解释,这造成了她普遍被人质疑的一点,就是如果代码中出现运行时错误时难以调试,不过从实际使用上来看,因为CoffeeScript的编译结果大部分情况下自然而合理。

这种静态编译还有一个额外的好处,就是CoffeeScript和现有的环境(浏览器,Node,Rhino等)与库完全兼容

简单介绍入门

注释
在coffeeScript中,注释均采用 # 符号

# single line comment
### 
  multi line comment
###    

关于语句后加  的问题

在js中,如果认为当前语句和随后语句是一个整体的话,就不会自己加;,比如以下javascript代码

//javascript code
var y = x+f
(a+b).toString()

//parsed to:
var y = x+f(a+b).toString();

---CoffeeScript在编译时为每条语句加上;,因此在代码中不需要写;

作用域

在js中最糟糕的设计就是全局变量,当你忘记用var声明变量的时候,这个变量会成为全局对象上的一个属性
CoffeeScript避免了这点

输入:foo = "bar"

编译后:

(function() {
  var foo;
  foo = "bar";
}).call(this);

任何的代码都会使用Immediate Function包装,这样foo成为了本地变量,并且,可以通过call指定的this引用全局对象

为了方便起见,之后的编译后代码描述不会再加上这个包装

实际上在CoffeeScript中,你也不需要再用var声明变量,编译后会自动加上var,并且将声明hoisting,即放到作用域的顶部,看一个来自官方文档的例子
输入:

outer = 1
change = ->
  inner = -1
  outer = 10
inner = change()

->是函数定义的简写方式,之后我们会探讨(当时使用的是ES2015还未有ES6的剪头语法)
编译后:

var change, inner, outer;

outer = 1;

change = function() {
  var inner;
  inner = -1;
  return outer = 10;
};

inner = change();

赋值

首先是字符串可以用类ruby的语法内嵌

target = "world"
alert "hello, #{target}"

其次是字面量,可以用类似YAML的方法定义对象字面量

object1 = one: 1, two: 2
object2 =
  one: 1
  two: 2
  class: "numbers"

注意保留字class,现在可以直接作为对象的key了

数组也可以分行

arr = [
  1
  2
]

数组

数组的操作引入了来自ruby的Range概念,并且可以将字符串完全作为数组操作

numbers = [0..9]
numbers[3..5] = [-3, -4, -5]
my = "my string"[0..1]

判断一个值是否在数组内,在js中可以用Array.prototype.indexOf,不过IE8及以下不支持,CoffeeScript提供了跨浏览器的in操作符解决

arr = ["foo", "bar"]
"foo" in arr

编译后:

 var arr,
   __indexOf = [].indexOf || function(item) { 
     for (var i = 0, l = this.length; i < l; i++) { 
       if (i in this && this[i] === item) 
         return i; 
     } 
     return -1; 
   };

arr = ["foo", "bar"];

__indexOf.call(arr, "foo") >= 0;

也具有过滤器when

prisoners = ["Roger", "Roderick", "Brian"]
release prisoner for prisoner in prisoners when prisoner[0] is "R"

看起来很像普通英语了,也可以用()收集遍历的结果

result = (item for item in array when item.name is "test")

流程控制

CoffeeScript使用来自ruby的省略语法,让控制流变得很紧凑,也引进了unless,not,then等语法糖式的关键字

result = if not true then "false"
result = unless true then "false"

取消了js中的==判断,改成全部用===进行严格比较,js中的==会做大量诡异的类型转换,很多情况下是bug的来源

if "1" == 1 
  alert("equal")
else
  alert("not equal")

在使用if来进行空值的判断时,js有时会让人困扰,因为""和0都会被转换成false,Coffee提供了?操作符解决这个问题,她只有在变量为null或undefined时才为false

""? #true
null? #false

也可以用常见的类似ruby中||=的方法,判断赋值,此外还可以用and,or,is关键字代替&&,||,==

hash or= {}
hash ?= {}

经常有当某个属性存在的时候,才会调用属性上的方法的情况,这时候也可以用?

knight.hasSword()?.poke()

只有当hasSword()返回对象不为空时,才会调用poke方法,以下是编译的js代码

var _ref;
if ((_ref = knight.hasSword()) != null) {
  _ref.poke();
}

switch case语句也有了一些语法糖,并且会默认加上break

switch day
  when "Sun" then go relax
  when "Sat" then go dancing
  else go work

函数

CoffeeScript对JavaScript的函数做了很大的简化,举个例子,看一个求和函数

sum = (nums...) ->
  nums.reduce (x, y) -> x+y

sum 1,2,3

对应JavaScript

var sum,
    __slice = [].slice;

sum = function() {
  var nums;
  nums = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
  return nums.reduce(function(x, y) {
    return x + y;
  });
};

sum(1, 2, 3);
  • 可以使用和ruby 1.9类似的lambda函数写法->来代替function
  • 参数列表放在->的前边,且可省略
  • 取消了函数声明,只能将函数作为值定义
  • 在CoffeeScript中,任何语句都是表达式(除了break和continue),都有返回值,因此像ruby一样,不需要显- 式return
  • js的函数参数有一个很讨厌的地方,就是参数对象arguments不是一个真正的数组,要使用数组方法,必须- 转换成数组[].slice.call(arguments, 0)这样,而在CoffeeScript中收束(加...)的参数是一个真正的数组

CoffeeScript的函数可以有默认参数,如

times = (a = 1, b = 2) -> a * b

CoffeeScript的函数调用可以不用()语法包围参数,像ruby一样跟在函数名后面就可以,不过这也有时候会带来问题,特别是没有参数的调用
alert

总结

如果有兴趣的小伙伴,可以到coffeeScript中文网 ,继续学习。
虽然是一个糖果版的JavaScript,但是还是 给予javaScript,对于学习专研,还是要以javaScript为准。至于CoffeeScript是一个非常好的书写规范,让javaScript更加简洁易懂。ES6的出现也是根据CoffeeScript的亮点进行优化的。所以目前ES6已经覆盖了CoffeeScript的70%的功能点了。随着ES2017将在6月份推出,相信有更多的惊喜值得我们发现!

你可能感兴趣的:(CoffeeScript)