Хорошо, моя первая попытка объяснить, что я делал, с треском провалилась. Я в основном копирую Object.create () Крокфорда, за исключением частных переменных.
Если вы посмотрите на принятый ответ здесь Как наследовать от класса в javascript? , вы увидите Object.create как последний шаблон, который, я думаю, лучше соответствует прототипной природе Javascript (объекты объекты beget) вместо эмуляции классического наследования (классы объектов beget).
Если вы посмотрите статью Википедии о программировании на основе прототипов (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
Способ, которым я сделал функцию "from", заключается в том, что когда родительский объект меняет свои методы, если вы хотите предотвратить изменение в дочернем экземпляре, вы можете указать:
this.public_method = this.parent.public_method;
в дочернем экземпляре.
Обратите внимание, что объекты, созданные ex nihilo, не наследуются от Object (hasOwnProperty и т. Д.). Вы должны явно указать это как .from (Object).
Преимущества этого шаблона:
- Память не тратится впустую для каждого нового экземпляра
- Придерживается истинного шаблона наследования прототипа
- У вас есть доступ к родительскому объекту с помощью this.parent (this .__ proto__ зависит от браузера)
- Закрытые переменные теперь существуют
Есть один существенный недостаток этого метода, о котором я могу подумать: синтаксис 'function ()' может ввести людей в заблуждение, полагая, что функция назначается переменной вместо объекта.
У меня вопрос, есть ли другие недостатки, которые я пропускаю? (Не включайте недостатки шаблона-прототипа - это субъективно - но только моей реализации).