课程表

CoffeeScript 语法

CoffeeScript 类和对象

CoffeeScript 字符串

CoffeeScript 数组

CoffeeScript 日期和时间

CoffeeScript 数学

CoffeeScript 方法

CoffeeScript 元编程

CoffeeScript jQuery

CoffeeScript 正则表达式

CoffeeScript 网络

CoffeeScript 设计模式

CoffeeScript 数据库

CoffeeScript 测试

工具箱
速查手册

检测与构建丢失的函数

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

问题

你想要检测一个函数是否存在,如果不存在则构建该函数。(比如 Internet Explorer 8 的 ECMAScript 5 函数)。

解决方案

使用存在赋值运算符(?=)来把函数分配给类库的原型(使用 :: 简写),然后把它放于一个立即执行函数表达式中(do ->)使其含有所有变量。

  1. do -> Array::filter ?= (callback) ->
  2. element for element in this when callback element
  3. array = [1..10]
  4. array.filter (x) -> x > 5
  5. # => [6,7,8,9,10]

讨论

在 JavaScript (同样地,在 CoffeeScript)中,对象都有一个原型成员,它定义了什么成员函数能够适用于基于该原型的所有对象。
在CoffeeScript中,你可以使用 :: 捷径来访问这个原型。所以如果你想要把过滤函数添加至数组类中,就执行 Array::filter = ... 语句。它能把过滤函数加至所有数组中。

但是,不要去覆盖一个在第一时间还没有构造的原型。比如,如果 Array::filter = ... 已经以快速本地形式存在于浏览器中,或者库制造者拥有其对于 Array::filter = ... 的独特版本,这样以来,你要么换一个慢速的 JavaScript 版本,要么打破这种依赖于其自身 Array::shuffle 的库。
你需要做的仅仅是在函数不存在的时候添加该函数。这就是存在赋值运算符(?=)的意义。如果我们执行 Array::filter = ... 语句,它会首先判断 Array::filter 是否已经存在。如果存在的话,它就会使用现在的版本。否则,它会添加你的版本。

最后,由于存在的赋值运算符在编译时会创建一些变量,我们会通过把它们封装在立即调用函数表达式( IIFE )中来简化代码。这将隐藏那些内部专用的变量,以防止泄露。所以假如我们写的函数已经存在,那么它将运行,基本上什么都没做然后退出,绝对不会对你的代码造成影响。但是假如我们写的函数并不存在,那么我们发送出去的仅是一个作为闭包的函数。所以只有你写的函数能够对代码产生影响。无论哪种方式,?= 的内部运行都会被隐藏。

举例

接下来,我们用上述的方法编译了 CoffeeScript 并附加了说明:

  1. // (function(){ ... })() 是一个 IIFE, 使用 `do ->` 来编译它。
  2. (function() {
  3. // 它来自 `?=` 运算符,用来检查 Array.prototype.filter (`Array::filter`) 是否存在。
  4. // 如果确实存在,我们把它设置给其自身,并返回。如果不存在,则把它设置给函数,并返回函数。
  5. // The IIFE is only used to hide _base and _ref from the outside world.
  6. var _base, _ref;
  7. return (_ref = (_base = Array.prototype).filter) != null ? _ref : _base.filter = function(callback) {
  8. // `element for element in this when callback element`
  9. var element, _i, _len, _results;
  10. _results = [];
  11. for (_i = 0, _len = this.length; _i < _len; _i++) {
  12. element = this[_i];
  13. if (callback(element)) {
  14. _results.push(element);
  15. }
  16. }
  17. return _results;
  18. };
  19. // The end of the IIFE from `do ->`
  20. })();
转载本站内容时,请务必注明来自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号