Как лучше понять миксины Coffeescript / JavaScript? - PullRequest
14 голосов
/ 04 января 2012

Я читал на Mixins, используя Coffeescript или просто обычный Javascript из следующих источников:

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

Вот как я это прочитал:

  • create literal ORM.
  • Объявите метод find, принимающий параметр.
  • Объявите метод 'create', принимающий параметр.
  • Объявите метод "расширенный", с под-методом "include", с под-методом "save".

Вот где я больше всего потерян.

У литерала ORM есть метод extended, и затем Module реализуется / расширяется классом User.Так что я понимаю, что User имеет ту же форму, что и Module.Эта часть до сих пор имеет смысл, упрощенное наследование.Но тогда я заблудился на @extend ORM.

@extend - это метод Module, но что делает метод extended?Когда это называется?Как это реализовано?

Ответы [ 2 ]

5 голосов
/ 04 января 2012
  • extend копирует методы из объекта "модуль" в расширяемый объект
  • include копирует методы из объекта "module" в прототип расширяемого объекта

1 moduleKeywords используется для защиты некоторых методов модуля, поэтому они не копируются в объект, поскольку имеют особое значение

2 extended?.apply(@) говорит, что , если модуль имеет свойство с именем extended, тогда предположите, что это функция, а затем вызовите эту функцию, указав "this" в функции, равной @, @ является расширенным объектом , вы можете думать об этом как о чем-то вроде (хотя и не совсем, но это просто интуиция) @.extended() (@ == это в coffeescript)

функция «применить» в JS
экзистенциальный оператор в CS

0 голосов
/ 04 января 2012

Вас смущает значение и использование для расширенных и включенных ключевых слов модуля. Но в книге объясняется, что они используются как обратные вызовы после расширения и включения.

Итак, в последнем примере ORM «расширил» обратный вызов. Функция "extended" будет при окончательном вызове "extended" и передавать ее @ (или this или в нашем примере User), поэтому @ (this.) Include будет также выполняться для пользователя и будет включать функцию "save".

Вы также можете сделать обратное:

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

class User extends Module
  @include ORM
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...