Можем ли мы назвать это настоящим прототипом наследования? - PullRequest
1 голос
/ 04 мая 2011

Я всегда поражен тем, как люди пытаются навязать некую форму классического наследования в javascript. Я разработал метод для наследования в некотором объекте b методов-прототипов от объекта a, без добавления методов-прототипов от объекта b к объекту a, и возможности использовать частные переменные из объекта, унаследованного от 1 . Теперь мне любопытно: вы бы сказали, что это действительно прототипное «наследство»? Это жизнеспособный метод? Есть ли в нем питтфалы?

Вот пример кода:

Object.prototype.inheritsFrom = function(obj){
    var prototo   = this.prototype, 
        protofrom = obj.prototype;
    for (var l in protofrom) {
        if (protofrom.hasOwnProperty(l)){
            prototo[l] = protofrom[l];
        }
    }
}

function Obj1(){
    var const1 = 25;
    if (!Obj1.prototype.getConst1){
       Obj1.prototype.getConst1 = function(){
           return const1;
       }
    }
}

function Obj2(){
    var const2 = 50;
    if (!Obj2.prototype.getConst2){
       Obj2.prototype.getConst2 = function(){
           return const2;
       }
    }
    Obj2.inheritsFrom(Obj1);
}

var instanceA = new Obj1,
    instanceB = new Obj2;

Теперь instanceA содержит метод getConst1, instanceB содержит методы getConst1 и getConst2, как вы можете видеть в this jsfiddle .

1 Назначая методы-прототипы в функции конструктора, эффективно используя созданное этим замыкание.

1 Ответ

3 голосов
/ 04 мая 2011

Нет, это не прототип наследования. В истинном наследовании прототипа изменения в прототипе появляются в объектах, которые полагаются на этот прототип. В вашем примере это не так, потому что они только скопированы.

Я не говорю, что в некоторых ситуациях это не может быть другой полезной формой наследования, но это не прототип. В некотором смысле я даже не уверен, что это наследство, хотя я думаю, что можно спорить об этом в любом случае, и это не имеет значения, независимо от этого.

Вот пример добавления к прототипу:

function Parent() {
}
Parent.prototype.foo = function() {
  display("foo!");
};

function Child() {
}
Child.prototype = new Parent();

var c = new Child();

display("[before] typeof c.foo === '" + typeof c.foo + "'");
// shows "[before] typeof c.foo === 'function'"
display("[before] typeof c.bar === '" + typeof c.bar + "'");
// shows "[before] typeof c.bar === 'undefined'"
display("Note that c.bar is currently undefined");

Parent.prototype.bar = function() {
  display("bar!");
};

display("[after] typeof c.bar === '" + typeof c.bar + "'");
// shows "[after] typeof c.bar === 'function'"
display("Now c.bar is a function");

c.foo();
c.bar();

Живая копия

Обратите внимание, что это не туманный случай. В конце концов, ваш собственный код полагается на изменения в Object.prototype, отражаемые в других вещах (Function), которые уже получены из него.


Не по теме : Настоятельно рекомендуем никогда не добавлять ничего к Object.prototype. Это сломает огромный объем кода, который предполагает, что использование for..in на {} не даст никаких свойств. Пока вы не сможете надежно пометить добавления как не перечисляемые (ECMAScript5 теперь предоставляет способ сделать это, но в большинстве реализаций его пока нет), просто держитесь подальше от Object.prototype. Просто рекомендация. Кроме того, в вашем случае это не имеет смысла, потому что inheritsFrom работает только для Function экземпляров, поэтому вы захотите добавить его вместо Function.prototype (что намного менее опасно).

...