由于Base
是一个构造函数,如果你想使用Base.prototype
作为它的基础,为Brian Peacock points out below你可以使用构造一个对象:
var concrete2 = new Base();
concrete2.notify(); // Works
如果您想进一步的功能添加到concrete2
例如,您可以直接做到这一点:
concrete2.doSomethingElse = function() { /* ... */ };
这工作,因为你已经有一个构造函数,所以要建立由construc支持单个对象的最简单方法tor的原型是使用new
操作符。
但是,有时您希望在与构造函数没有关联的情况下使用对象,或者您有一个不想调用该构造函数的原因。在这些情况下(我给下面一个的例子),你可以使用Object.create
,这是在ES5并且可以在旧的浏览器被部分匀:
// Creates an object backed by Base.prototype without calling Base
var concrete2 = Object.create(Base.prototype);
concrete2.notify(); // Works
Object.create
直接创建一个新对象,并设置其原型到你传入它的对象。
if (!Object.create) {
Object.create = function(proto, props) {
if (typeof props !== "undefined") {
throw "The two-argument version of Object.create cannot be shimmed.";
}
function ctor() { }
ctor.prototype = proto;
return new ctor();
};
}
的一种用途是通过与其他一些代码的标记了一个问题为例:它的单参数版本可以在旧的浏览器,这也是有用的知道它做什么来垫高问题,它使用一种常见但不是理想的方式来设置Concrete1
和Base
之间的继承关系。这是问题的行:
Concrete1.prototype = new Base(); // Not ideal
的问题是:如果有什么Base
做一些事情,应该只有特定实例?例如,假设它接受特定于实例的参数? (这是一个,但只有一个,方法Base
可能包含特定于实例的代码。)调用Base
几乎从来都不是为其“子类”设置原型的正确方法。相反,您使用Object.create
:
Concrete1.prototype = Object.create(Base.prototype); // Better
...通常依次为:
Concrete1.prototype.constructor = Concrete1;
...只是因为这是规范如何定义函数实例的原型属性(它表示constructor
将作为函数,但实际上从未实际使用constructor
)。
然后你从Concrete1
函数调用Base
时,其创建一个实际的实例:
function Concrete1(any, necessary, args) {
Base.call(this, any, necessary); // For example
this.args = args; // For example
}
完整的示例:
function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
Person.prototype.getFullName = function() {
return this.firstName + " " + this.lastName;
};
/* ...further Person-specific functions put on Person.prototype here...*/
function Employee(firstName, lastName, jobTitle) {
Person.call(this, firstName, lastName);
this.jobTitle = jobTitle;
}
Employee.prototype = Object.create(Person.prototype);
Employee.prototype.constructor = Employee;
/* ...Employee-specific functions put on Employee.prototype here...*/
function Manager(firstName, lastName, jobTitle) {
Employee.call(this, firstName, lastName);
this.jobTitle = jobTitle;
}
Manager.prototype = Object.create(Employee.prototype);
Manager.prototype.constructor = Manager;
/* ...Manager-specific functions put on Manager.prototype here...*/
...等等。 (或者使用一个脚本像我Lineage
剧本,这也有助于supercalls和简化的东西公平一点。)
错字错误,抱歉。是'concrete2' – Catalin