【问题标题】:Javascript Classical Inheritance calling parentJavascript 经典继承调用父级
【发布时间】:2013-11-03 07:13:55
【问题描述】:

我想通过应用经典继承在扩展的 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 Fiddle

问题是该方法没有在扩展类中被调用,而只是在父类(Person)中被调用。

【问题讨论】:

  • 你打错了this

标签: javascript inheritance super


【解决方案1】:

这是因为覆盖的 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().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);

【讨论】:

  • 感谢您的回答,但这样给构造函数的参数是未定义的。警报:John Doe,30 个警报:呼叫员工警报:未定义,未定义
【解决方案2】:
// ...

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

【讨论】:

    猜你喜欢
    • 2013-11-07
    • 1970-01-01
    • 2015-10-12
    • 2016-01-18
    • 1970-01-01
    • 1970-01-01
    • 2016-05-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多