0

Я пытаюсь понять, как работают прототипы. У меня есть этот пример:Как совместить функцию конструктора и свойство прототипа

function Person(name) { 
    if (arguments.length > 0) 
     this.init(name); 
} 

Person.prototype.init = function(name) { 
    this.name = name(); 
} 
Employee.prototype = new Person(); 

function Employee (name, id) { 
    if (arguments.length > 0) { 
     this.init(name); 
     this.id = id; 
    } 
} 

var employee = new Employee("frank",01); 
alert(employee.name);//returns frank 

Я пытаюсь выяснить, как объединить первые два раздела, и назначить «INIT» свойство в функции конструктора. У меня есть, но это ничего не возвращает:

function Person(name) { 
    if (arguments.length > 0) 
     this.init = function(name) { 
    this.name = name; 
     } 
} 
Employee.prototype = new Person(); 

function Employee (name, id) { 
    if (arguments.length > 0) { 
     this.init(name); 
     this.id = id; 
    } 
} 

var employee = new Employee("frank",01); 
alert(employee.name);//returns nothing 

Я предполагаю, что я делаю что-то неправильно в присвоении инициализации, но я не знаю, что. Изменение начального свойства на

this.init(name) = function(name) { 

также не работает.

+1

Не пытайтесь использовать какой-либо метод 'init' вообще! Просто выполните работу в конструкторе! – Bergi

ответ

1

В вашем втором фрагменте кода, если вы изменили одну строку несколько

Employee.prototype = new Person('bob'); 

код будет уже работал (Сотрудник по-прежнему является «откровенным»)

Проблема заключается в конструкторе

function Person(name) { 
    // create member 'init' ONLY if an argument was passed to the constructor 
    if (arguments.length > 0) 
     this.init = function(name) { 
      this.name = name; 
     } 
} 

Как уже было сказано в другом ответе, изменяя прототип Person изменяет все экземпляры класса Person и

Person.prototype.init = function(name) { ... } 

создает функцию init члена в каждом случае Person. Но в вашем конструкторе есть условие, где init будет создано только в том случае, если был аргумент.

Линии

Employee.prototype = new Person(); 

состояние, что каждый экземпляр класса Employee будет иметь все элементы, которые имеют объект на правой стороне. В этом случае - новый экземпляр Person

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

2

Вы хотите передать имя init-property от Employee to Person?

Это делается так:

// Create a constructor-function for your Person-Object. 
function Person(name) { 
    this.name = name; 
} 

// Create the constructor-function for an Employee-Object that extends Person 
function Employee(name) { 
    // Call the constructor-function from Person 
    Person.call(this, name); 
} 

// Let the prototype of Employee be Person.prototype (Employee extends Person) 
Employee.prototype = Object.create(Person.prototype); 
// By changing the prototype of Employee we have lost our constructor-function Employee() 
// so we have to recover it. 
Employee.prototype.constructor = Employee; 

Может быть, вы ожидаете, что супер-конструктор будет вызываться неявно, как вы можете знать его от других языков, таких как Java. Но этого не происходит в JavaScript. Вы должны сделать это самостоятельно, позвонив

Person.call(this, name) 

Существует очень хороший JavaScript-учебник по MDN, который помог мне многое понять прототипы материала:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript

Совершит посмотрите главу «Пользовательские объекты». Думаю, я не мог объяснить это лучше.

Смежные вопросы