3

古典的な継承を適用​​して、拡張された JavaScript の「クラス」でスーパー メソッドを呼び出したい。

function Person(name, age) {
    this._name = name;
    this._age = age;
}
Person.prototype.exposeInfo = function() {
    alert(this._name + ' - ' + this._age);    
}

function Employee(name, age) {
    this.parent.constructor.call(this, name, age);
}
Employee.prototype.exposeInfo = function() {
    alert('Call employee');
    this.parent.exposeInfo();    
}

Employee.prototype = Object.create(Person.prototype);
Employee.prototype.constructor = Employee;
Employee.prototype.parent = Person.prototype;


var p1 = new Person('John Doe', 30);
p1.exposeInfo();

var p2 = new Employee('John Foobar (empl.)', 35);
p2.exposeInfo();

JSフィドル

問題は、メソッドが拡張クラスで呼び出されておらず、親 (Person) でのみ呼び出されていることです。

4

2 に答える 2

4

これは、オーバーライドexposeInfoが以前のオブジェクトにアタッチされ、prototypeその後置き換えられるためです。

Employee.prototype = Object.create(Person.prototype);

を作成した後にメソッドをアタッチして、順序を逆にする必要がありますprototype

Employee.prototype = Object.create(Person.prototype);
Employee.prototype.constructor = Employee;
Employee.prototype.parent = Person.prototype;

Employee.prototype.exposeInfo = function() {
    // ...
}

また、コンストラクターで行ったように.call()or.apply()を使用する必要があります。exposeInfo

Employee.prototype.exposeInfo = function() {
    alert('Call employee');
    this.parent.exposeInfo.apply(this, arguments);    
}

それ以外の場合、 の値はthis最後のメンバー演算子によって決定されます。

// so, calling:
this.parent.exposeInfo();

// is equivalent to:
alert(this.parent._name + ' - ' + this.parent._age);
于 2013-10-24T14:14:56.750 に答える
0
// ...

Employee.prototype = Object.create(Person.prototype);
Employee.prototype.constructor = Employee;
Employee.prototype.parent = Person.prototype;

Employee.prototype.exposeInfo = function() {
  this.parent.exposeInfo.apply(this, arguments);
  // ...
}

うまくいきません。

例:

// ...

Employee.prototype = Object.create(Person.prototype);
Employee.prototype.constructor = Employee;
Employee.prototype.parent = Person.prototype;

Employee.prototype.exposeInfo = function() {
  this.parent.exposeInfo.apply(this, arguments);
  // ...
}

ParttimeEmployee = Object.create(Employee.prototype);
ParttimeEmployee.prototype.constructor = ParttimeEmployee;
ParttimeEmployee.prototype.parent = Employee.prototype;

ParttimeEmployee.prototype.exposeInfo = function() {
  this.parent.exposeInfo.apply(this, arguments);
  // ...
}

var p1 = new Person('Jack', 30);
p1.exposeInfo(); // ok

var p2 = new Employee('Jane', 25);
p2.exposeInfo(); // ok

var p3 = new ParttimeEmployee('John', 20);
p3.exposeInfo(); // infinite recursion !!!

正しいバージョン:

// Person
function Person(name, age) {
  this._name = name;
  this._age = age;
}
Person.prototype.exposeInfo = function() {
  alert(this._name + ' - ' + this._age);    
}

// Employee
Employee.prototype = Object.create(Person.prototype);
Employee.prototype.constructor = Employee;
Employee.parent = Person.prototype; // <--

Employee.prototype.exposeInfo = function() {
  Employee.parent.exposeInfo.apply(this, arguments); // <--
  // ...
}

// ParttimeEmployee
ParttimeEmployee = Object.create(Employee.prototype);
ParttimeEmployee.prototype.constructor = ParttimeEmployee;
ParttimeEmployee.parent = Employee.prototype; // <--

ParttimeEmployee.prototype.exposeInfo = function() {
  ParttimeEmployee.parent.exposeInfo.apply(this, arguments); // <--
  // ...
}

var p1 = new Person('Jack', 30);
p1.exposeInfo(); // ok

var p2 = new Employee('Jane', 25);
p2.exposeInfo(); // ok

var p3 = new ParttimeEmployee('John', 20);
p3.exposeInfo(); // ok
于 2015-11-15T14:21:09.170 に答える