考虑在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
而烦恼?
答案 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.prototype
与object.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