Как вы делаете наследование в JavaScript, не разделяя один и тот же экземпляр суперкласса между всеми экземплярами подкласса? - PullRequest
6 голосов
/ 05 января 2012

Я заметил, что каждый урок о том, как сделать наследование JavaScript, делает это:

SubClass.prototype = new SuperClass();

Но это создаст один экземпляр суперкласса и поделит его со всеми экземплярами подкласса.

Проблема в том, что я хотел бы передать аргументы конструктору суперкласса, которые берутся из аргументов, передаваемых подклассу.

В Java это будет сделано так:

class SubClass extends SuperClass {
  public SubClass(String s) {
    super(s);
  }
}

Я пытался сделать что-то вроде этого:

function SubClass(args) {
  this.constructor.prototype = new SuperClass(args);
}

Но это не сработает.Так есть ли способ сделать это в JavaScript?

Ответы [ 4 ]

5 голосов
/ 05 января 2012

Общий шаблон следующий:

Создан временный конструктор, который наследуется от прототипа родительского конструктора. Затем прототип дочернего конструктора устанавливается на экземпляр временного конструктора.

function inherits(Child, Parent) {
    var Tmp = function() {};
    Tmp.prototype = Parent.prototype;
    Child.prototype = new Tmp();
    Child.prototype.constructor = Child;
}

Внутри дочернего конструктора вам нужно вызвать конструктор родителя:

function Child(a, b, c) {
    Parent.call(this, a, b);
}

inherits(Child, Parent);

// add prototype properties here

Внутри этого вызова функции this будет ссылаться на новый объект, который создается при вызове new Child(), следовательно, независимо от того, какая инициализация выполняется внутри Parent, она применяется к новому объекту, который мы передаем. *

2 голосов
/ 05 января 2012

Так я всегда делал.

// Parent object
function Thing(options)
{ 
    //do stuff
}

Thing.prototype.someMethod = function(){
    // some stuff
   console.log('hello');
}

// child object which inherits from the parent
function OtherThing(options)
{       
    Thing.call(this, options);
    // do stuff for otherthing
}

OtherThing.prototype = new Thing();

OtherThing.prototype.someMethod = function(){
   // call things original function
   Thing.prototype.someMethod.call(this);

   // now do anything different
   console.log('other thing says hi');
}


var testObj = new OtherThing();
    testObj.someMethod();

Демонстрация в реальном времени

1 голос
/ 05 января 2012

Но это создаст один экземпляр суперкласса и разделит его между всеми экземплярами подкласса.

Да, именно так работает наследование в JavaScript.

Так есть ли способ сделать это в JavaScript?

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

0 голосов
/ 05 января 2012

Другим способом было бы избавиться от наследственного (но не основанного на классах) наследования, связанного с использованием конструктора.

Используйте Object.create вместе с Object.defineProperties. Это основано на собственной системе наследования на основе прототипов, которой придерживается JavaScript.

Более подробную информацию можно найти в спецификациях MDN и ECMAScript.

Однако эти методы работают только в браузерах, совместимых с ECMAScript 5. Это исключает IE8 и старше. К счастью, IE9 поддерживает его, как и остальные основные браузеры. В конце концов, я думаю, что это будет путь.

...