课程表

CoffeeScript 语法

CoffeeScript 类和对象

CoffeeScript 字符串

CoffeeScript 数组

CoffeeScript 日期和时间

CoffeeScript 数学

CoffeeScript 方法

CoffeeScript 元编程

CoffeeScript jQuery

CoffeeScript 正则表达式

CoffeeScript 网络

CoffeeScript 设计模式

CoffeeScript 数据库

CoffeeScript 测试

工具箱
速查手册

函数绑定及其他

当前位置:免费教程 » JS/JS库/框架 » CoffeeScript

函数绑定

JavaScript 当中 this 关键字被动态地设定为当前函数挂载所在的对象上. 如果你把函数当作回调, 或者挂载到别的对象, 那么原先的 this 就丢失了. 如果你不了解这个行为, If you're not familiar with this behavior, this Digital Web article 对怪异模式做了很好的回顾.

Fat arrow => 可以同时定义函数, 绑定函数的 this 到当前的值, 正是我们需要的. 这有助于在 Prototype 或者 jQuery 这种基于回调的类库当中使用, 用于创建迭代器函数传递给 each, 或者借助 bind 的事件处理器函数. Fat arrow 定义的函数可以访问到他们创建位置的 this 对象的属性.

CoffeeScript:
  1. Account = (customer, cart) ->
  2. @customer = customer
  3. @cart = cart
  4.  
  5. $('.shopping_cart').bind 'click', (event) =>
  6. @customer.purchase @cart
编译成JS:
  1. var Account;
  2.  
  3. Account = function(customer, cart) {
  4. this.customer = customer;
  5. this.cart = cart;
  6. return $('.shopping_cart').bind('click', (function(_this) {
  7. return function(event) {
  8. return _this.customer.purchase(_this.cart);
  9. };
  10. })(this));
  11. };

如果上边用的是 this, @customer 会指向一个 DOM 元素的 undefined "customer" 属性, 然后强行调用上面的 purchase() 时会抛出一个异常.

对于类的定义, 实例创建的过程中 fat arrow 定义的方法会自动绑定到类的每个示例上去。


嵌入 JavaScript

这个写法应该不会被用到, 但如果什么时候需要在 CoffeeScript 中穿插 JavaScript 片段的话, 你可以用反引号直接传进去。

CoffeeScript:
  1. hi = `function() {
  2. return [document.title, "Hello JavaScript"].join(": ");
  3. }`
编译成JS:
  1. var hi;
  2.  
  3. hi = function() {
  4. return [document.title, "Hello JavaScript"].join(": ");
  5. };

Switch/When/Else

JavaScript 里的 Switch 语句有点难看. 你需要在每个 casebreak 防止自动进入默认的 case. CoffeeScript 会阻止掉意外的 fall-through. 而且 switch 编译的结果会是可以带 return, 可以被用于赋值的表达式. 格式这样写: switch 判断条件, when 然后子句, else 然后默认的 case.

就像 Ruby, CoffeeScript 里边 switch 语句对于每个子句可以带多个值. 任何一个值匹配的情况下, 子句就会执行.

CoffeeScript:
  1. switch day
  2. when "Mon" then go work
  3. when "Tue" then go relax
  4. when "Thu" then go iceFishing
  5. when "Fri", "Sat"
  6. if day is bingoDay
  7. go bingo
  8. go dancing
  9. when "Sun" then go church
  10. else go work
编译成JS:
  1. switch (day) {
  2. case "Mon":
  3. go(work);
  4. break;
  5. case "Tue":
  6. go(relax);
  7. break;
  8. case "Thu":
  9. go(iceFishing);
  10. break;
  11. case "Fri":
  12. case "Sat":
  13. if (day === bingoDay) {
  14. go(bingo);
  15. go(dancing);
  16. }
  17. break;
  18. case "Sun":
  19. go(church);
  20. break;
  21. default:
  22. go(work);
  23. }

Switch 语句也可以不写控制条件, 当作 if/else 调用链的一个更整洁的可选写法。

CoffeeScript:
  1. score = 76
  2. grade = switch
  3. when score < 60 then 'F'
  4. when score < 70 then 'D'
  5. when score < 80 then 'C'
  6. when score < 90 then 'B'
  7. else 'A'
  8. # grade == 'C'
编译成JS:
  1. var grade, score;
  2.  
  3. score = 76;
  4.  
  5. grade = (function() {
  6. switch (false) {
  7. case !(score < 60):
  8. return 'F';
  9. case !(score < 70):
  10. return 'D';
  11. case !(score < 80):
  12. return 'C';
  13. case !(score < 90):
  14. return 'B';
  15. default:
  16. return 'A';
  17. }
  18. })();

Try/Catch/Finally

Try/catch 语句基本上 JavaScript 的一样(尽管它们是表达式执行)。

CoffeeScript:
  1. try
  2. allHellBreaksLoose()
  3. catsAndDogsLivingTogether()
  4. catch error
  5. print error
  6. finally
  7. cleanUp()
编译成JS:
  1. var error;
  2.  
  3. try {
  4. allHellBreaksLoose();
  5. catsAndDogsLivingTogether();
  6. } catch (_error) {
  7. error = _error;
  8. print(error);
  9. } finally {
  10. cleanUp();
  11. }

链式对比(Chained Comparisons)

CoffeeScript 从 Python 学习了 链式对比 — 这样判断数值是否在某个范围内在写法上更容易.

CoffeeScript:
  1. cholesterol = 127
  2.  
  3. healthy = 200 > cholesterol > 60
编译成JS:
  1. var cholesterol, healthy;
  2.  
  3. cholesterol = 127;
  4.  
  5. healthy = (200 > cholesterol && cholesterol > 60);

字符串替换, 块级的字符串, 块级的注释

Ruby 风格的字符串替换也在 CoffeeScript 实现了。 双引号包裹的字符串允许数据替换, 用 #{ ... } 语法,而单引号包裹的字符串仅仅是字面量。

CoffeeScript:
  1. author = "Wittgenstein"
  2. quote = "A picture is a fact. -- #{ author }"
  3.  
  4. sentence = "#{ 22 / 7 } is a decent approximation of π"
编译成JS:
  1. var author, quote, sentence;
  2.  
  3. author = "Wittgenstein";
  4.  
  5. quote = "A picture is a fact. -- " + author;
  6.  
  7. sentence = "" + (22 / 7) + " is a decent approximation of π";

CoffeeScript 支持多行字符串. 行与行会用一个空格拼接, 除非结尾用了反斜杠. 其中缩进会被忽略。

CoffeeScript:
  1. mobyDick = "Call me Ishmael. Some years ago --
  2. never mind how long precisely -- having little
  3. or no money in my purse, and nothing particular
  4. to interest me on shore, I thought I would sail
  5. about a little and see the watery part of the
  6. world..."
编译成JS:
  1. var mobyDick;
  2.  
  3. mobyDick = "Call me Ishmael. Some years ago -- never mind how long precisely -- having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world...";
  4. loadrun: mobyDick

块级的字符串可以用于书写格式化的或者对缩进敏感的文本(或者你只是不想转义单引号双引号)。代码块开始的位置的缩进层级会被保留, 用在后面的代码中, 所以这部分代码依然可以跟整体的代码一起对齐。

CoffeeScript:
  1. html = """
  2. cup of coffeescript
  3. """
编译成JS:
  1. var html;
  2.  
  3. html = "\n cup of coffeescript\n";

块级的字符串用双引号, 跟普通的双引号字符串一样, 支持替换。

有时候你想把整块的注释传给生成的 JavaScript。 比如在文件顶部嵌入协议。 块级的注释, 仿照了块级字符串的语法, 将会在生成的代码当中保留。

CoffeeScript:
  1. ###
  2. SkinnyMochaHalfCaffScript Compiler v1.0
  3. Released under the MIT License
  4. ###
编译成JS:
  1. /*
  2. SkinnyMochaHalfCaffScript Compiler v1.0
  3. Released under the MIT License
  4. */

块级的正则表达式

类似块级的字符串跟注释, CoffeeScript 支持块级的正则 — 扩展了正则表达式, 可以忽略内部的空格, 可以包含注释和替换. 模仿了 Perl 的 /x 修饰符, CoffeeScript 的块级正则以 /// 为界, 让正则表达式获得了很大程度的可读性. 引用一下 CoffeeScript 源码:

CoffeeScript:
  1. OPERATOR = /// ^ (
  2. ?: [-=]> # 函数
  3. | [-+*/%<>&|^!?=]= # 复合赋值 / 比较
  4. | >>>=? # 补 0 右移
  5. | ([-+:])\1 # 双写
  6. | ([&|<>])\2=? # 逻辑 / 移位
  7. | \?\. # soak 访问
  8. | \.{2,3} # 范围或者 splat
  9. ) ///
编译成JS:
  1. var OPERATOR;
  2.  
  3. OPERATOR = /^(?:[-=]>|[-+*\/%<>&|^!?=]=|>>>=?|([-+:])\1|([&|<>])\2=?|\?\.|\.{2,3})/;

Cake和Cake文件

CoffeeScript包含一个类似GNU MakeRuby的 Rake的构建系统,很自然的,它被称作Cake。它用于构建任务和测试CoffeeScript语言本身。任务被包含在一个Cake文件(cakefile)里,并且可以通过在目录运行Cake任务进行调用。要查看所有的任务选项和设置,只需输入cake命令。

任务的定义是CoffeeScript编写的,所以你可以把任意代码放在cakefile里。定义包含如下内容:任务名称、任务的具体描述,以及任务在运行时调用的函数。如果您的任务需要一个命令行选项,您可以用短和长的标志来定义选项,并且它将在选项对象中可用。这里有一个任务例子,使用Node.js API重建CoffeeScript的解析器:

CoffeeScript:
  1. fs = require 'fs'
  2.  
  3. option '-o', '--output [DIR]', 'directory for compiled code'
  4.  
  5. task 'build:parser', 'rebuild the Jison parser', (options) ->
  6. require 'jison'
  7. code = require('./lib/grammar').parser.generate()
  8. dir = options.output or 'lib'
  9. fs.writeFile "#{dir}/parser.js", code
编译成JS:
  1. var fs;
  2.  
  3. fs = require('fs');
  4.  
  5. option('-o', '--output [DIR]', 'directory for compiled code');
  6.  
  7. task('build:parser', 'rebuild the Jison parser', function(options) {
  8. var code, dir;
  9. require('jison');
  10. code = require('./lib/grammar').parser.generate();
  11. dir = options.output || 'lib';
  12. return fs.writeFile("" + dir + "/parser.js", code);
  13. });

如果您需要在调用一个任务前调用另一个,例如,在run函数前前运行build函数,您可以使用invoke函数:invoke 'build'。Cake任务是一个调用CoffeeScript功能命令行的最简短方式,所以不要期待任何花哨的功能。如果你需要调用某些必须的功能,或异步回调,最好把它们放在你的代码本身,而不是Cake任务里。

转载本站内容时,请务必注明来自W3xue,违者必究。
 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号