Сегодня я видел синтаксис 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;
}
1: Вызов def ('Person')
возвращает функцию, которая вызывается с объектом в качестве параметра. Это тот же принцип, что и:
function x() {
return function(y) { alert(y); }
}
x()('Hello world!');
2: Оператор <<
является оператором сдвига влево. Он сдвигает целочисленное значение на определенное количество бит влево. Я не нашел никаких ссылок для его другого использования, и в Javascript нет перегрузки оператора, поэтому я не могу понять, использовать его в функции. Пока мне это кажется опечаткой.
Как объяснил Тим, оператор сдвига используется только для вызова метода valueOf
. Это работает как перегрузка всех операторов, принимая исходную цель и делая что-то совершенно другое.
Вау, это было достаточно запутано, чтобы мой крошечный мозг мог понять, но теперь я чувствую себя намного лучше, зная, как это работает :) Спасибо @Tim за указание на valueOf ()
уловка.
Общий случай создания «класса»
с использованием:
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