由於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