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

我假设我在分配 init 时做错了,但我不知道是什么。将初始属性更改为

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

也不行。

4

2 回答 2

2

您想将初始化属性名称从 Employee 传递给 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)

MDN 上有一个非常好的 JavaScript-Tutorial 帮助我理解原型的东西:

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

看看“自定义对象”一章。我想我无法更好地解释它。

于 2014-07-06T15:24:29.703 回答
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更改 class 的所有实例Person,并且

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

init在 的每个实例中创建一个成员函数Person。但是在您的构造函数中有一个条件,init只有在有参数的情况下才会创建 where 。

线

Employee.prototype = new Person();

声明,类的每个实例都Employee将具有所有成员,在右侧有一个对象。在这种情况下 - 的新实例Person

顺便说一句,不建议在类构造函数中定义函数成员,因为每次调用构造函数时,都需要创建一个新函数。而在修改原型的情况下,函数只创建一次,并与对象的所有实例共享。

于 2014-07-06T15:32:48.583 回答