原型:这两个脚本之间的区别

时间:2014-12-16 12:01:57

标签: javascript

考虑在JavaScript中构建对象层次结构的这两个版本:

版本1

function Employee() {
    this.name = "NoName";
    this.dept = "NoDept";
};

function Manager() {
    Employee.call(this);
    this.reports = "Nobody";
}

//Manager.prototype = Object.create(Employee.prototype);
var m = new Manager();
console.log(m.name);

版本2

function Employee() {
    this.name = "NoName";
    this.dept = "NoDept";
};

function Manager() {
    //Employee.call(this);
    this.reports = "Nobody";
}

Manager.prototype = Object.create(Employee.prototype);
var m = new Manager();
console.log(m.name);

在第一个版本中,即使我们不使用原型继承(当然因为name方法),也可以访问call()属性。在第二个版本中,我们注释掉call()并定义原型链,但name属性无法访问。

这让我想知道,为什么还要为Manager.prototype而烦恼?

2 个答案:

答案 0 :(得分:2)

请注意,在构造函数中:

function Employee() {
    this.name = "NoName";
    this.dept = "NoDept";
}

当被称为:

new Employee();

name dept 属性将直接添加到分配给 this 的新对象中。它们没有被继承,它们直接在实例上。

  

在第一个版本中,即使我们不使用原型继承,也可以访问name属性

因为当你这样做时:

Employee.call(this);

您正在将 name 属性直接添加到 Manager 的实例中。它不是继承的,而是直接在实例上。

  

在第二个版本中,我们注释掉call()并定义原型链,但name属性不可访问

因为名称属性不在原型链上,所以 Employee 构造函数将其直接放在 this 上(这将是通常是 Employee 的实例,但由于您从 Manager 调用它的方式,它是 Manager 的实例。)

  

这让我想知道,为什么还要使用Manager.prototype呢?

因此 Manager 的实例将继承自 Employee.prototype 。但是你还没有向 Employee.prototype 添加任何方法,所以没有任何东西可以继承。

答案 1 :(得分:1)

为什么Manager.prototypeobject.create结合在一起。因为如果你不使用它,它将不会继承你的基础/超级班的原型方法'员工'。通常在实际情况下,您的超类将具有您想要继承的原型方法,并且在该场景中object.create为您提供了一种更简单的方法来实现这一点。
请考虑以下示例

function Employee() {
    this.name = "NoName";
    this.dept = "NoDept";
};
Employee.prototype.method1 = function(){//super class method
 alert("super method");   
}

function Manager() {
    Employee.call(this);//inherit direct properties
    this.reports = "Nobody";
}

Manager.prototype = Object.create(Employee.prototype);//inherit prototype
var m = new Manager();
m.method1();//commenting out object.create will not allow this access