// 以 function 為建構子
function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
//然後活化類別
var p = new Person("Dino", "Wang");
如你所見這樣的類別並不具有"成員函式",所以當你需要成員函式時你可能會手動繫結上去
// 附加一個匿名函式到 p 實體
p.fullName = function () {
return this.firstName + " " + this.lastName;
}
這樣的問題是,每一個被活化的類別都需要進行一次上述動作(以下稱為成員繫結),如果你這類別會產生多個物件,就會造成匿名函式重複產生的問題(浪費記憶體)
正確而有效的做法是進行 prototype 宣告,將類別定義修改如下
function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
Person.prototype.fullName = function () { return this.firstName + " " + this.lastName; }
var p = new Person("Dino", "Wang");
var fullName = p.fullName(); // Workable!
此後每一個被活化的 Person 類別都自動具有 fullName 成員函式,不需要額外進行繫結值得一提的是,javascript 允許你對已經定義過的類別,附加成員,還且還會一併讓已經被活化的物件也具有這份"原型",例如:
// 你可以為 String 擴充 trim() 功能
String.prototype.trim = function () { return this.replace(/^\s*|\s*$/g, ""); }
var name = " Dino ".trim();
// 為 Array 增加 append() 以模擬出 .NET Framework 效率較高的 StringBuilder
Array.prototype.append = function (val) { this.push(val); return this; }
var sb = [].append("1").append("2").append("3").join(" ");
常用的 javascript 版本(1.2) 沒有常見的 class 的定義方式,因為它是 prototype-oriented
NOTE: 關於 javascript 對比到一般物件導向語言的 繼承、類別成員、靜態成員 的方式,簡單整理如下:
// Constructor
function SuperClass() {}
// SuperClass behaviors
SuperClass.prototype.toString = function () {
return "I'm super class.";
}
// Constructor
function UserClass() {
SuperClass.apply(this, arguments); // Call constructor, like C# base(...)
}
// Inheritance
UserClass.prototype = new SuperClass;
// Data member
UserClass.prototype.property1 = 0;
UserClass.prototype.property2 = 0;
// Member function
UserClass.prototype.method1 = function () {}
UserClass.prototype.method2 = function () {}
// Static data member
UserClass.instances = 0;
UserClass.cache = [];
// Static member function
UserClass.staticMethod1 = function () {}
UserClass.staticMethod2 = function () {}
沒有留言:
張貼留言