Этот синтаксис JavaScript, который я не видел до настоящего времени, что он делает действительно?

Сегодня я видел синтаксис JavaScript (при вызове функции), который незнаком мне. Это было похоже:

def('Person') ({
  init: function(name) {this.name=name;}
  ,speak: function(text) {alert(text || 'Hi, my name is ' + this.name);}
});

, и

def('Ninja') << Person ({
  kick: function() {this.speak('I kick u!');}
});

1: Что происходит с объектом в круглых скобках в первом примере? Это обрабатывается def функционируйте так или иначе, но я не понимаю то, что продолжается здесь (см. def функция ниже). Где делает объектное движение?

2: О том же самом снова, но использовании << оператор, что я никогда не замечаемый (я думаю!). О чем то, что все?

Код из http://gist.github.com/474994, где Joe Dalton сделал маленькую вещь наследования OO JavaScript (это - по-видимому, ветвление чужой работы, но вполне полностью переписанный, поскольку это кажется). Возможно, Вы хотите проверить его там на материал, на который ссылаются def функция, которую я даю Вам здесь:

function def(klassName, context) {
  context || (context = global);

  // Create class on given context (defaults to global object)
  var Klass =
    context[klassName] = function Klass() {

      // Called as a constructor
      if (this != context) {

        // Allow the init method to return a different class/object
        return this.init && this.init.apply(this, arguments);
      }

      // Called as a method
      // defer setup of superclass and plugins
      deferred._super = Klass;
      deferred._plugins = arguments[0] || { };
    };

  // Add static helper method
  Klass.addPlugins = addPlugins;

  // Called as function when not
  // inheriting from a superclass
  deferred = function(plugins) {
    return Klass.addPlugins(plugins);
  };

  // valueOf is called to set up
  // inheritance from a superclass
  deferred.valueOf = function() {
    var Superclass = deferred._super;
    if (!Superclass)
        return Klass;
    Subclass.prototype = Superclass.prototype;
    Klass.prototype = new Subclass;
    Klass.superclass = Superclass;
    Klass.prototype.constructor = Klass;
    return Klass.addPlugins(deferred._plugins);
  };
  return deferred;
}

22
задан Peter Mortensen 11 April 2015 в 23:16
поделиться

2 ответа

1: Вызов def ('Person') возвращает функцию, которая вызывается с объектом в качестве параметра. Это тот же принцип, что и:

function x() {
  return function(y) { alert(y); }
}

x()('Hello world!');

2: Оператор << является оператором сдвига влево. Он сдвигает целочисленное значение на определенное количество бит влево. Я не нашел никаких ссылок для его другого использования, и в Javascript нет перегрузки оператора, поэтому я не могу понять, использовать его в функции. Пока мне это кажется опечаткой.

Изменить:

Как объяснил Тим, оператор сдвига используется только для вызова метода valueOf . Это работает как перегрузка всех операторов, принимая исходную цель и делая что-то совершенно другое.

13
ответ дан 29 November 2019 в 05:44
поделиться

Вау, это было достаточно запутано, чтобы мой крошечный мозг мог понять, но теперь я чувствую себя намного лучше, зная, как это работает :) Спасибо @Tim за указание на valueOf () уловка.

Общий случай создания «класса» с использованием:

def ("ClassName") ({
    init: function() { .. },
    foo: function() { .. }
});

тривиален, поскольку первый вызов def возвращает функцию, которая принимает объект и копирует свойства переданного объекта в прототип ClassName .

Более интересный случай использования << для создания подкласса зависит от порядка оценки выражения, а также от попытки принуждения любого объекта к значению неявным вызовом valueOf ( ) . Основной трюк - это, по сути, общая переменная, которая записывает суперкласс и применяемые к нему свойства. Выражение

def("ClassName") << ParentClass({ .. })

будет вычислено следующим образом: вызывается

  1. def ("ClassName") , который создает глобальный объект ClassName и возвращает его функцию-конструктор. Назовем этот возвращаемый объект - initializeMeLater .
  2. ParentClass (..) Вызывается , который сохраняет ссылку на ParentClass и переданный объект / свойства в совместно используемой переменной.
  3. Вызывается initializeMeLater.valueOf () , который получает ссылку на родительский класс и свойства из этой общей переменной и устанавливает прототипы.
  4. valueOf вызывается для возвращаемого значения с шага 2, что бесполезно и не имеет никакого эффекта, поскольку мы уже установили отношения суперклассов на шаге 3.

Код пытается имитировать синтаксис Ruby для создания подклассов. который выглядит примерно так:

class Child < Parent
    def someMethod
        ...
    end
end
5
ответ дан 29 November 2019 в 05:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: