在MDN JavaScript指南的“Property inheritance revisited”部分下,它解释了属性继承的一些细微之处。
我特别感兴趣的是一个关于递增id的例子:
var idCounter = 1;
function Employee (name, dept) {
this.name = name || "";
this.dept = dept || "general";
this.id = idCounter++;
}
function Manager (name, dept, reports) {...}
Manager.prototype = new Employee;
function WorkerBee (name, dept, projs) {...}
WorkerBee.prototype = new Employee;
function Engineer (name, projs, mach) {...}
Engineer.prototype = new WorkerBee;
function SalesPerson (name, projs, quota) {...}
SalesPerson.prototype = new WorkerBee;
var mac = new Engineer("Wood, Mac");
基本上,它继续说这个的完整版本(每个构造函数都有一个'base'属性,它也在原型链中调用它们上面的构造函数)将意味着mac.id将是5.
据我所知,每次创建一个Employee对象时,id值都会增加1,但是在创建'mac'之前4次确实创建了一个Employee对象? 如果有人能够一步一步地给我这个过程,我将不胜感激。
答案 0 :(得分:3)
使用new
将调用构造函数。每当调用构造函数时(通过new
或通常的方式()
,call
或apply
),id都会递增。所以我们算一下:
Manager.prototype = new Employee; //1
//...
WorkerBee.prototype = new Employee; //2
到目前为止这是两个。如果你在代码下考虑这个重要的句子:
进一步假设此处省略的定义包含
base
property和在原型链中调用它们上面的构造函数。
这基本上意味着代码中的{...}
部分是这样的:
function Manager (name, dept, reports) {
Employee.apply(this, arguments);
}
This jsFiddle显示没有这些省略号的代码(最小化实现)。
所以这些都会调用Employee
函数:
Engineer.prototype = new WorkerBee; //3
//...
SalesPerson.prototype = new WorkerBee; //4
//...
var mac = new Engineer("Wood, Mac"); //5
答案 1 :(得分:0)
John Resig在how to use class-based inheritance上有一篇优秀的文章和简单的帮助函数。这使得从基类继承更容易,而无需调用构造函数。
这是我自己的解释:
为了使Manager
继承Employee
,Manager.prototype
实际上必须是Employee
的实例。因此,Manager.prototype = new Employee
实际上会立即执行Employee
构造函数。
解决这个问题的唯一方法是将构造函数逻辑放入一个单独的方法,例如init
:
function Employee() { /* EMPTY CONSTRUCTOR */ }
Employee.prototype.init = function(name, dept) {
this.name = name || "";
this.dept = dept || "general";
this.id = idCounter++;
}
function Manager(name, dept, reports) {
this.init(name, dept); // Calls the base constructor
}
Manager.prototype = new Employee();