如何更好地理解Coffeescript/JavaScript混合

How to better understand Coffeescript/JavaScript mixins?

本文关键字:Coffeescript JavaScript 混合 何更好 更好      更新时间:2023-09-26

我一直在从以下来源阅读使用Coffeescript或纯Javascript的Mixins:

http://arcturo.github.com/library/coffeescript/03_classes.html(接近底部)

http://javascriptweblog.wordpress.com/2011/05/31/a-fresh-look-at-javascript-mixins/

当我能够编译各种各样的例子时,我有一个主要的问题似乎阻碍了我在理解它们方面取得进展。

我不知道到底发生了什么事。首先,我将解释一下让我困惑的Coffeescript。

moduleKeywords = ['extended', 'included']
    class Module
      @extend: (obj) ->
        for key, value of obj when key not in moduleKeywords
          @[key] = value
        obj.extended?.apply(@)
        this
      @include: (obj) ->
        for key, value of obj when key not in moduleKeywords
          # Assign properties to the prototype
          @::[key] = value
        obj.included?.apply(@)
        this
这里出现了许多问题。
  1. 首先,我们用moduleKeywords变量完成了什么?我不明白这是怎么回事。

  2. 其次,extended?.apply(@)是如何工作的?这里到底发生了什么?我可以查看JavaScript编译并看到以下代码:

Module.extend = function(obj) {
      var key, value, _ref;
      for (key in obj) {
        value = obj[key];
        if (__indexOf.call(moduleKeywords, key) < 0) {
          this[key] = value;
        }
      }
      if ((_ref = obj.extended) != null) {
        _ref.apply(this);
      }
      return this;
    };
谁能解释一下这个问题?

The Little Book on Coffeescript的深处,我看到了一个实现。

ORM = 
  find: (id) ->
  create: (attrs) ->
  extended: ->
    @include
      save: -> 
class User extends Module
  @extend ORM

我是这样读的:

  • 创建文字ORM
  • 声明方法find接受参数。
  • 声明方法"create"接受一个参数。
  • 声明方法'extended',子方法'include',子方法'save'。

这是我最容易迷路的地方。

文字ORM有一个方法extended,然后Module由'类' User实现/扩展。所以我认为这意味着UserModule具有相同的形状。到目前为止,这部分是有道理的,简单的继承。但后来我在@extend ORM上迷路了。

@extendModule上的方法,但是extended方法在做什么?什么时候叫?它是如何实现的?

  • extend将"module"对象的方法复制到被扩展的对象上
  • include将"module"对象中的方法复制到原型被扩展对象

1 moduleKeywords是用来保护模块的一些方法,所以没有被复制到对象中,因为它们有特殊的意义

2 extended?.apply(@)如果模块有一个名为extended的属性,那么假设它是一个函数,然后调用这个函数,函数中的"this"等于@,@是扩展对象,你可以把它想象成(虽然不完全,但这只是一种直觉)@.extended() (@ == this in coffeescript)

JS中的"apply"函数
CS

中的存在运算符

您对扩展的包含的模块关键字的含义和使用感到困惑。但是在书中解释了这些在扩展和包含。之后用作回调

所以在最后的例子中ORM有"扩展"回调。"extend"函数将在结束时调用"extended"并传递给它@(或this或在我们的示例中User),所以@(this.)include也将在User上运行,它将包含函数"save"。

你也可以反过来做:

ORM = 
  save ->
  included: ->
    @extend
      find: (id) ->
      create: (attrs) ->
class User extends Module
  @include ORM