Наследование в JS: this.base = Class ();this.base () или ...? - PullRequest
7 голосов
/ 05 июля 2011

Я пытаюсь «получить» наследство в JS.Я только что обнаружил удобный способ в основном копировать все свойства из одного объекта в другой:

function Person(name){
  this.name="Mr or Miss: "+name;

  this.introduce = function(){
    console.log("Hi, I am "+this.name);
  }
}

function Employee(name,title){
  this.title=title;

  this.base=Person;
  this.base(name);  

}

e = new Employee('tony', 'manager')
e.introduce();

Обратите внимание, что у меня есть класс Person () с конструктором, и его атрибут "name" генерируется конструктором,Самое замечательное в этом также то, что тогда сотрудник имеет ТАКЖЕ имя в конструкторе - и вуаля ', он создает объект Person, используя тот же параметр.

Если бы я сделал это с помощью метода "Прототип":

function Person(name){

  this.introduce = function(){
    console.log("Hi, I am "+this.name);
  }
}

function Employee(name, title){
  this.name = name; /*  ?!?!?!?!? I can't call the proper constructor here */
  this.title = title;
}
Employee.prototype= new Person(); /* ?!?!? NO NAME HERE..>? */
Employee.prototype.constructor = Employee;


e = new Employee('tony', 'manager')
e.introduce();

Э-э-э ... что теперь?Я даже не могу завершить это: this.name в Employee нельзя установить с помощью правильного конструктора Person;создание объекта Person происходит только один раз в наследстве.

Итак ... что мне не хватает?Является ли первый пример, который я дал, «подходящим» способом в моем случае?И есть ли способ получить тот же результат со вторым примером?

Справка!

Ответы [ 2 ]

12 голосов
/ 05 июля 2011

Этот тип наследования прототипа часто выполняется следующим образом:

function Parent() {}

function Child() {
    Parent.call(this); // call the constructor of the parent
}

var Constr = function() {};
Constr.prototype = Parent.prototype;

Child.prototype = new Constr();
Child.prototype.constructor = Child;

Таким образом, «хитрость» состоит в том, чтобы назначить Parent.prototype в качестве прототипа для пустой функции и установить новый экземпляр этой функции какпрототип Child.

Это сделано для того, чтобы расширение Child.prototype не расширяло Parent.prototype.

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

В вашем примере это будет выглядеть так:

function Employee(name,title){
  this.title=title;

  Person.call(this, name);
}

без назначения конструкторасвойство экземпляра.

В вашем примере this.base(name) работает, потому что, присваивая конструктор свойству экземпляра (и вызывая его таким образом), this внутри функции ссылается на этот экземпляр.


Существует несколько библиотек, реализующих этот шаблон, например, Библиотека Google Closure :

goog.inherits = function(childCtor, parentCtor) {
  /** @constructor */
  function tempCtor() {};
  tempCtor.prototype = parentCtor.prototype;
  childCtor.superClass_ = parentCtor.prototype;
  childCtor.prototype = new tempCtor();
  childCtor.prototype.constructor = childCtor;
}; 
1 голос
/ 23 июня 2018
function Parent(){
    this.lastName='Jackson';
    this.inheritedLastName=function(){
         console.log("Last Name will be Inherited By Child",this.lastName);
     }
}

function Child(){
  Parent.call(this);//Super constructor call...to initialise lastName
  this.firstName='Michael';
}
Child.prototype.fullName=function(){
  console.log(`Full Name is ${this.firstName} ${this.lastName}`);
}
Object.setPrototypeOf(Child.prototype,Parent.prototype);
//It sets Child Prototype to that of Parent while keeping Child Original prototype Intact
//Ensures That prototype of Parent appear in Child.

var michaelJackson = new Child();
michaelJackson.lastName;//Inherited class fields
michaelJackson.inheritedLastName();//able to call Parent method

michaelJackson.fullName();
//able to call child method.
//Also we have access to lastName from parent inheritance thus completely inheriting Parent.

Явный Super Call необходим для инициализации lastName в нашем классе

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...