初识 CoffeeScript

很早就晓得这CoffeeScript一门言语,然则一向没有机会体系的进修下,那天趁在公司没有什么要紧的项目做,就依据CoffeeScript首页的例子学了一下。

援用CoffeeScript的一段引见:

CoffeeScript 是一门编译到 JavaScript 的玲珑言语. 在 Java 般愚笨的表面下, JavaScript 实在有着一颗华美的心脏. CoffeeScript 尝试用简约的体式格局展现 JavaScript 优异的部份. CoffeeScript 的指点原则是: 
“她仅仅是 JavaScript”. 代码一一对应地编译到 JS, 不会在编译过程当中举行诠释. 已有的 JavaScript 类库能够无缝地和 CoffeeScript 搭配运用, 反之亦然. 编译后的代码是可读的, 且经由美化, 能在一切 JavaScript 环境中运转, 而且应当和对应手写的 JavaScript 一样快或许更快.

—- 来自CoffeeScript中文

本身是写PHP的,最最先打仗CoffeeScript的时刻,就被他吸收了,由于它竟然能够不必括号、分号就能够辨认语法划定规矩,在用jQuery编写一些事宜的时刻常常会写回调函数,常常在末了留下一大串的 });

运用CoffeeScript就能够写出很幽美的Js的代码了,别的还能够很好的防备局部变量由于不加var而援用到全局变量。而形成一些稀里糊涂的毛病。

下面是本身的一些笔记:

一、装置

由于CoffeeScript是基于nodejs的,所以起首须要装置nodejs (这家伙也不错,竟然能够让js运转在服务端),在nodejs下载响应平台的版本就能够了,我这里运用CentOS体系。

wget -c http://nodejs.org/dist/v0.10.26/node-v0.10.26.tar.gz
tar -zxvf node-v0.10.26.tar.gz -C /usr/local/src/
cd /usr/local/src/
./configure
make && make install

当装置胜利了后能够运用

npm -v

测试是不是装置胜利~   假如没有该敕令看看是不是是PATH没有到场。

运用npm包管理东西装置CoffeeScript(为了加速装置速率,能够运用淘宝NPM镜像)

装置CoffeeScript

npm install -g coffee-script

肯定装置胜利

coffee -v
CoffeeScript Version 1.7.1

 

二、Hello World

2.1编译一个第一个coffeeScript文件

coffee敕令参数:

-c, --compile编译一个 .coffee 剧本到一个同名的 .js 文件.
-m, --map随 JavaScript 文件一同天生 source maps. 而且在 JavaScript 里加上 sourceMappingURL 指令.
-i, --interactive启动一个交互式的 CoffeeScript 会话用来尝试一些代码片断. 等同于实行coffee 而不加参数.
-o, --output [DIR]将一切编译后的 JavaScript 文件写到指定文件夹. 与 –compile 或 –watch 搭配运用.
-j, --join [FILE]编译之前, 按参数传入递次衔接一切剧本到一同, 编译后写到指定的文件. 关于编译大型项目有效.
-w, --watch看管文件转变, 任何文件更新时从新实行敕令.
-p, --printJavaScript 直接打印到 stdout 而不是写到一个文件.
-s, --stdio将 CoffeeScript 通报到 STDIN 后从 STDOUT 猎取 JavaScript. 对其他言语写的历程有优点. 比方: cat src/cake.coffee | coffee -sc
-l, --literate将代码作为 Literate CoffeeScript 剖析. 只会在从 stdio 直接传入代码或许处置惩罚某些没有后缀的文件名须要写明这点.
-e, --eval直接从敕令行编译和打印一小段 CoffeeScript. 比方: coffee -e “console.log num for num in [10..1]”
-b, --bare编译到 JavaScript 时去掉顶层函数的包裹.
-t, --tokens不对 CoffeeScript 举行剖析, 仅仅举行 lex, 打印出 token stream:[IDENTIFIER square] [ASSIGN =] [PARAM_START (] …
-n, --nodes不对 CoffeeScript 举行编译, 仅仅 lex 和剖析, 打印 parse tree:

Expressions
  Assign
    Value "square"
    Code "x"
      Op *
        Value "x"
        Value "x"
--nodejs node 敕令有一些有用的参数, 比方 –debug, –debug-brk, –max-stack-size, 和 –expose-gc. 用这个参数直接把参数转发到 Node.js. 重复运用 –nodejs 来通报多个参数.

我习气 这么用:coffee -c -w -o ./js hello.coffee 如许就能够就能够平常编写一边编译,并把编译后的js文件放到指定的文件夹中。

写一个coffee文件:

#打印出Hello World
Console.log "Hello World"

编译敕令:

coffee -c hello.coffee

会在同级目次下天生一个同名的js文件。

能够直接运用node敕令实行js文件 或许在html中引入让浏览器来实行 ,这里用node直接实行:

node hello.js

Hello World!完成 我们看看coff帮我们编译成了什么模样的js。

// Generated by CoffeeScript 1.7.1
(function() {
console.log("Hello World!");
}).call(this);

CoffeeScript 将js包裹在了一个匿名函数当中,并用call(this)挪用,如许使得js代码断绝,不会和外部殽杂。

 2.2 作用域

在js中定义变量须要加上var,然则在CoffeeScript中你不须要如许做,直接

age=22
name="silenceper"
say=(arg)->
 console.log "my name is "+arg
say name

对应的js以下:

// Generated by CoffeeScript 1.7.1
(function() {
 var age, name, say;

 age = 22;

 name = "silenceper";

 say = function(arg) {
 var str;
 str = "my name is " + arg;
 return console.log(str);
 };

 say(name);

}).call(this);

能够看到一切的全局变量都会被定义在最顶层,函数内部的局部变量也被加上var定义,防备和局部变量殽杂。这一点异常有效,之前就遇到过如许的题目,由于定义了一个变量,恰好这个变量就是dom的id,而我又没有加上var声明,致使ie以为这是一个dom对象,而涌现一些莫名巧妙的毛病,固然另有许多,置信写js的人也遇到过如许的题目。

2.3 函数

我已在上面运用了函数,它是经由过程->的情势来定义一个函数,有参数的话就在前面的括号中写参数,然后经由过程空格 缩进来示意函数体。

2.4  if/else/unless

实在跟js差不多  只不过运用起来越发轻易了,它不须要你加括号、分号来辨别,这里也是运用空格、缩进来处置惩罚。

day="Thursday"
if day is "Saturday" or "Sunday"
    go "rest"
else
    go "work"

coffeeScript跟js中推断的对照

《初识 CoffeeScript》

另有存在性推断:就是在变量的后边加上一个?

solipsism = true if mind? and not world?

speed = 0
speed ?= 15

footprints = yeti ? "bear"

2.5 轮回

运用for/in 完成数组的轮回,运用for/of 完成对象的轮回

for/in示例:

eat food for food in ['toast', 'cheese', 'wine']

关于的js

var _ref,food,_i;
_ref = ['toast', 'cheese', 'wine'];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
  food = _ref[_i];
  eat(food);
}

for/of 示例:

yearsOld = max: 10, ida: 9, tim: 11

ages = for child, age of yearsOld
  "#{child} is #{age}"

注重:个中的#{}就是变量的替换

2.6  switch/when/else

运用官方的示例:

 

switch day
  when "Mon" then go work
  when "Tue" then go relax
  when "Thu" then go iceFishing
  when "Fri", "Sat"
    if day is bingoDay
      go bingo
      go dancing
  when "Sun" then go church
  else go work

对应的js:

switch (day) {
  case "Mon":
    go(work);
    break;
  case "Tue":
    go(relax);
    break;
  case "Thu":
    go(iceFishing);
    break;
  case "Fri":
  case "Sat":
    if (day === bingoDay) {
      go(bingo);
      go(dancing);
    }
    break;
  case "Sun":
    go(church);
    break;
  default:
    go(work);
}

2.7 类/继续

直接参考官方的示例:

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()

对应的js:

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();

实在在javascript当中并没有class,extends 如许的用法,只不过为了让运用起来轻易,CoffeeScript许可你如许简朴的运用。

经由过程视察编译后的js发明,它是经由过程一个__extends方法来完成继续这一用法的,实在也是经由过程变动prototype来完成。

个中的@name 示意的就是this.name

CoffeeScript为了轻易运用prototype,能够运用双冒号来替换prototype。

说说解释:

单行解释:运用一个#,这类解释体式格局不会被编译进js当中

#这是单行解释

多行解释:运用三个#最先,三个#完毕。这类解释体式格局会被编译为/**/的情势

###
这是多行解释
###

实在CoffeeScript当中另有许多巧妙便利的功用,你能够在CoffeeScript首页的例子中找到。

 

在github中能够找到许多CoffeeScript写的js项目,能够多看看!

别的另有一个js转CoffeeScript的东西:https://github.com/js2coffee/js2coffee

原文地点:http://silenceper.com/archives/1108.html

    原文作者:silenceper
    原文地址: https://segmentfault.com/a/1190000000489945
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞