如何更好地理解 Coffeescript/JavaScript mixins?

发布于 2024-12-25 05:41:39 字数 2319 浏览 2 评论 0原文

我一直在使用 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. 其次,extend?.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”接受参数。
  • 声明方法“扩展”,使用子方法“包含”,使用子方法“保存”。

这是我最迷失的地方。

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

@extendModule 上的一个方法,但是 extend 方法是做什么的呢?什么时候叫?它是如何实施的?

I have been reading up on Mixins using Coffeescript or just plain Javascript from the following sources:

http://arcturo.github.com/library/coffeescript/03_classes.html (near the bottom)

and

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

And while I am able to compile the various examples, I have a major question that seems to be preventing me from making progress in comprehending them.

I have no idea what in the world is going on. To start, I will explain the Coffeescript that is confusing me.

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

A number of questions come up here.

  1. First of all, what are we accomplishing with the moduleKeywords variable? I'm not understanding what that is doing.

  2. Secondly, how does extended?.apply(@) work? What is really going on here? I can look at the JavaScript compilation and see the following code ..

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;
    };

Can anyone shed some general light on this?

From deeper down in The Little Book on Coffeescript, I see an implementation.

ORM = 
  find: (id) ->
  create: (attrs) ->
  extended: ->
    @include
      save: -> 

class User extends Module
  @extend ORM

Here is how I read this:

  • create literal ORM.
  • Declare method find accepting a parameter.
  • Declare method 'create' accepting a parameter.
  • Declare method 'extended', with sub-method 'include', with sub-method 'save'.

This is where I get the most lost.

The literal ORM has a method, extended, and then Module is implemented/extended by the 'class' User. So I take this to mean that User has the same shape as Module. That part makes sense so far, simplistic inheritance. But then I get lost on @extend ORM.

@extend is a method on Module, but what is the extended method doing? When is it called? How is it implemented?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

‘画卷フ 2025-01-01 05:41:39
  • extend 将方法从“模块”对象复制到正在扩展的对象上
  • include 将方法从“模块”对象复制到被扩展的对象的原型上被扩展的对象

1 moduleKeywords 用于保护模块的某些方法,因此不会复制到对象,因为它们具有特殊含义

2 extended?.apply(@)< /code> 表示如果模块有一个名为extended的属性,而不是假设它是一个函数,然后调用这个函数,函数中的“this”等于@,@是扩展对象,你可以把它想象成这样类似于(虽然不完全是,但这只是一种直觉)@.extended()(咖啡脚本中的@ == this)

JS 中的“apply”函数
CS 中的存在运算符

  • extend copies the methods from the "module" object onto the object being extended
  • include copies the methods from the "module" object onto the prototype of the object being extended

1 The moduleKeywords is used to protect some methods of the module, so the are not copied to object, because they have special meaning

2 The extended?.apply(@) says that if the module has a property named extended than assume it's a function and then call this function having the "this" in the function equal to @, @ being the extended object, you can think of it as saying something like (although not quite, but it's just an intuition) @.extended() (@ == this in coffeescript)

"apply" function in JS
the existential operator in CS

你如我软肋 2025-01-01 05:41:39

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

所以在最后一个例子中,ORM 有“扩展”回调。 “extend”函数将在最后调用“extended”并将其传递给 @(或 this 或在我们的示例中为 User),因此 @(this.)include 也将在 User 上运行,并且它将包含函数“save”。

你也可以做相反的事情:

ORM = 
  save ->
  included: ->
    @extend
      find: (id) ->
      create: (attrs) ->

class User extends Module
  @include ORM

You are confused by meaning and use for extended and included Module keywords. But it is explained in book that those are used as callbacks after extending and including.

So in final example ORM has "extended" callback. The "extend" function will on end call "extended" and pass it @ (or this or in our example User) so @(this.)include will also run on User and it will include function "save".

You could also do the reverse:

ORM = 
  save ->
  included: ->
    @extend
      find: (id) ->
      create: (attrs) ->

class User extends Module
  @include ORM
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文