Вау, это было достаточно запутанно, чтобы мой крошечный мозг мог понять, но теперь я чувствую себя намного лучше, зная, как именно это работает :) Спасибо @Tim за указание на valueOf()
трюк.
Общий случай создания "class"
с использованием:
def ("ClassName") ({
init: function() { .. },
foo: function() { .. }
});
тривиален, так как первый вызов def
возвращает функцию, которая принимает объект, и копирует свойства переданного объекта впрототип ClassName
.
Более интересный случай использования <<
для подкласса основан на порядке вычисления выражения, а также на попытке принудительного приведения любого объекта к значению неявным вызовом valueOf()
.Основной трюк - это, по сути, общая переменная, которая записывает суперкласс и свойства, которые к нему применяются.Выражение
def("ClassName") << ParentClass({ .. })
будет оцениваться следующим образом:
def("ClassName")
вызывается, создает глобальный объект ClassName
и возвращает его функцию конструктора.Давайте назовем этот возвращенный объект - initializeMeLater
. ParentClass(..)
, который хранит ссылку на ParentClass
и переданный объект / свойства в общей переменной. initializeMeLater.valueOf()
вызывается, который получает ссылку на родительский класс и свойства из этой общей переменной и устанавливает прототипы. valueOf
вызывается для возвращаемого значения из шага 2, который бесполезен и имеетбезрезультатно, так как мы уже настроили отношение суперкласса на шаге 3.
Код пытается эмулировать синтаксис Ruby для создания подклассов, который выглядит следующим образом:
class Child < Parent
def someMethod
...
end
end