Хорошо, моя первая попытка попытки объяснить, что я делал, потерпела полный провал. Я в основном копирую Object.create Crockford (), кроме с частными переменными.
Если Вы смотрите на принятый ответ здесь, Как наследоваться классу в JavaScript?, Вы будете рассматривать Object.create как последний шаблон, который я передумываю, соответствует prototypal природе JavaScript (объекты порождают объекты) вместо того, чтобы эмулировать классическое наследование (классы порождают объекты).
При рассмотрении статьи Википедии об основанном на прототипе программировании (http://en.wikipedia.org/wiki/Prototype-based_programming) Вы видите больше того, что я имею в виду.
Недостаток с Object.create (), хотя то, что нет никакой поддержки членов парламента, не занимающих официального поста. Это - то, что я предлагаю:
Function.prototype.from = function(obj) {
function F() {this.parent = Object(obj);}
F.prototype = obj;
var out = new F();
this.apply(out);
return out;
};
Затем Вы создаете объекты как таким образом:
// Create an object
var a = function() {
var private_property = 'blue';
this.public_property = 7;
this.public_method = function() {
alert(this.public_property + ' ' + private_property);
}
}.from(null); // .from() works too, but .from(null) is more revealing
// Create a new object using 'a' as the prototype
var b = function() {
var private_property = 'red';
this.public_property = 8;
}.from(a);
// See the results
a.public_method(); // Alerts '7 blue'
b.public_method(); // Alerts '8 blue' - Parent methods use parent private variables
a.public_method = function() { alert('rabbit'); };
a.public_method(); // Alerts 'rabbit'
b.public_method(); // Alerts 'rabbit'
b.public_method = function() { alert('dog'); };
a.public_method(); // Alerts 'rabbit'
b.public_method(); // Alerts 'dog' - Parent method is overwritten
Путем я сделал "из" функции, таково, что, когда родительский объект изменяет свои методы, если Вы хотите предотвратить изменение в дочернем экземпляре, можно указать:
this.public_method = this.parent.public_method;
в дочернем экземпляре.
Обратите внимание также, что объекты, созданные исключая nihilo, не наследовались Объекту (hasOwnProperty, и т.д.). Необходимо явно указать это как .from (Объект).
Преимущества этого шаблона:
Существует один главный недостаток этого метода, о котором я могу думать: 'функция ()' синтаксис может смутить людей в размышление, что функция присвоена переменной вместо объекта.
Мой вопрос, там другие недостатки, которые я пропускаю? (Не включайте недостатки prototypal шаблона - это субъективно - но только моей реализации).
Во-первых, как уже упоминалось, подход Function.prototype
действительно вызывает затруднения. Почему бы не реализовать то же самое, например:
Object.createChild = function(obj, constructor) {
function F() { this.parent = Object(obj); }
F.prototype = obj;
var out = new F();
if (typeof constructor == 'function') {
constructor.apply(out);
}
return out;
};
Затем используйте
var a = Object.createChild(null, function () { /*...*/ });
var b = Object.createChild(a, function () { /*...*/ });
с теми же результатами, что и выше.
Бонус: вы можете опустить аргумент конструктор
, например:
var c = Object.createChild(anything);
Во-вторых, я не знаю, есть ли какое-либо применение в истинном прототипном наследовании, как вы его называете. В реальной жизни я почти уверен, что функция-конструктор специально адаптирована к расширяемому объекту ( a
). Таким образом, вы будете коллировать
var x = f.from(a);
var y = f.from(a);
с одной и той же комбинацией f
- a
снова и снова. И да, вы экономите несколько байтов памяти по сравнению с подходом, управляемым классами, но, честно говоря, кого это волнует?
Тем не менее, все это действительно хорошая идея в теории.