Huh. Мне кажется, что это намного сложнее, чем нужно.
На самом деле, более внимательно, я действительно делаю исключение из того, что он делает, предоставляя this._super()
, пока в методе, чтобы вызвать метод суперкласса.
код вводит зависимость от typeof==='function'
(ненадежной для некоторых объектов), Function#toString
(Argh, разложение функции является также ненадежным), и решить, нужно ли завернуть на основе уже ли вы использовали последовательность байт _super
в теле функции (даже если вы использовали его только в строке, и если вы попробуете, например, this['_'+'super']
, это не удастся).
И если вы сохраняете свойства объектов-объектов (например, MyClass.myFunction.SOME_PRIVATE_CONSTANT
, которые вы можете сделать, чтобы сохранить пространства имен чистыми), упаковка не позволит вам получить эти свойства. И если исключение выбрано в методе и поймано в другом методе того же объекта, _super
в конечном итоге укажет на неправильную вещь.
Все это только для того, чтобы упростить вызов метода супер-класса. Но я не думаю, что это особенно сложно сделать в JS. Это слишком умно для собственного блага и в процессе делает все менее надежным. (О, и arguments.callee
недействителен в строгом режиме, хотя это не его вина, так как это произошло после того, как он разместил его.)
Вот что я использую для занятий в данный момент. Я не утверждаю, что это «лучшая» система JS-класса, потому что есть загружает разных способов сделать это и кучу различных функций, которые вы можете добавить или не добавить. Но он очень легкий и нацелен на то, чтобы быть «JavaScriptic», если это слово. (Это не так.)
Function.prototype.makeSubclass= function() {
function Class() {
if (!(this instanceof Class))
throw 'Constructor function requires new operator';
if ('_init' in this)
this._init.apply(this, arguments);
}
if (this!==Object) {
Function.prototype.makeSubclass.nonconstructor.prototype= this.prototype;
Class.prototype= new Function.prototype.makeSubclass.nonconstructor();
}
return Class;
};
Function.prototype.makeSubclass.nonconstructor= function() {};
Он обеспечивает:
защита от случайного отсутствует new
. Альтернативой является тихое перенаправление X()
на new X()
, так что отсутствует new
работ. Это лучший результат; Я пошел на явную ошибку, так что вы не привыкли писать без new
и вызывают проблемы с другими объектами, не определенными так. В любом случае лучше, чем неприемлемый JS-дефолт, позволяющий this.
свойствам выпадать на window
и таинственным образом идет не так позже.
метод наследуемого _init
, поэтому вам не нужно писать конструктор-функцию, которая ничего не делает, кроме вызова функции конструктора суперкласса.
и все действительно все.
Вот как вы можете использовать его для реализации примера Resig в:
var Person= Object.makeSubclass();
Person.prototype._init= function(isDancing) {
this.dancing= isDancing;
};
Person.prototype.dance= function() {
return this.dancing;
};
var Ninja = Person.makeSubclass();
Ninja.prototype._init= function() {
Person.prototype._init.call(this, false);
};
Ninja.prototype.swingSword= function() {
return true;
};
var p= new Person(true);
p.dance(); // => true
var n = new Ninja();
n.dance(); // => false
n.swingSword(); // => true
// Should all be true
p instanceof Person &&
n instanceof Ninja && n instanceof Person
Superclass-колл делается специально именования метод, который вы хотите и call
ИНГ его, немного как в Python. Вы могли бы добавить элемент _super
к функции конструктора, если вы хотите избежать именования Person
(так что вы скажете Ninja._super.prototype._init.call
или, возможно, Ninja._base._init.call
).
Я видел Javascript «в производство ", из-за чего кричат кошки-ангелы из детского котенка, поэтому вам действительно нужно решить, какое влияние это повлияет на тестирование вашего устройства/страницы. Это такая простая вещь, что трудно представить, что это вызывает серьезные проблемы. – Pointy
+1 Пояс. Я только что критиковал ниже, но на самом деле 99% сайтов имеют более сомнительный код, чем тот, который у них уже есть ... – bobince
jQuery для начала ... –