Fork me on GitHub

Programming Design Notes

Javascript Object-Oriented Programming

| Comments

Javascript 也可以好像 java 一樣創造一個 Class

function Car(){
var price;
var name;

this.getPrice = function(){
return price;
}

this.getName = function(){
return name;
}

this.setPrice = function(aPrice){
price = aPrice;
}

this.setName = function(aName){
name = aName;
}
}

這樣便是一個 Class
使用 new 來創造一個實體

var car = new Car();
car.setPrice(50000);
car.setName("My Dream Car");
alert(car.getName());

你可能會問: Constructor 在那裡?
其實 Constructor 在 Car 的括號內

function Car(){
//............
}

我們可以改寫成為..
function Car(aPrice, aName){
var price = aPrice;
var name = aName;

this.getPrice = function(){
return price;
}

this.getName = function(){
return name;
}

this.setPrice = function(aPrice){
price = aPrice;
}

this.setName = function(aName){
name = aName;
}
}

我們創造 Car 的實體只需要..
var Car = new Car(50000, "My Dream Car");
alert(car.getName());

創造 Car 實體同時將 price 和 name 分配給 Car
在 Class 內的 var 代表 Private (私有)
表示這些 變數(variable) 或 function 不能夠被 Car 以外的 Class 存取
如果定義 function 為 Private (私有)
可以這樣:
function Car(aPrice, aName){
var price = aPrice;
var name = aName;

this.getPrice = function(){
return price;
}

this.getName = function(){
return name;
}

var setPrice = function(aPrice){
price = aPrice;
}

var setName = function(aName){
name = aName;
}
}

現在 setPrice 和 setName 都不能被 Car 以外的 Class 使用
而 this 代表 public (公用), var 代表 private (私用)
因為 Javascript 只有一個 Constructor
我認為不夠靈活
我會將 init 開頭的 function 作為 Constructor
Constructor 一定要是 Public function

function Car(){
var price;
var name;

this.init = function(){
return this;
}

this.initWithPrice = function(aPrice){
price = aPrice;
return this;
}

this.initWithName = function(aName){
name = aName;
return this;
}

this.initWithNamePrice = function(aName, aPrice){
name = aName;
price = aPrice;
return this;
}

this.getPrice = function(){
return price;
}

this.getName = function(){
return name;
}

this.setPrice = function(aPrice){
price = aPrice;
}

this.setName = function(aName){
name = aName;
}
}

這個做法是參考了 Objective C 的做法
創造 Car 實體時可以更有彈性

var car = new Car().init();
car.setPrice(50000);
car.setName("My Dream Car");
alert(car.getName());

var car1 = new Car().initWithPrice(40000);
car1.setName("My Dream Car 1");
alert(car1.getName());

var car2 = new Car().initWithNamePrice ("My Dream Car 2");
car2.setPrice(30000);
alert(car2.getName());

var car3 = new Car().initWithNamePrice ("My Dream Car 3", 30000);
alert(car3.getName());

現在介紹一下 Javascript Class 的繼承方法
我們製作一個 SuperCar 的 Class

function SuperCar(){
var hp;

this.getHP = function(){
return hp;
}

this.setHP = function(aHP){
hp = aHP;
}
}
完成了, 但現在還沒有繼承 Car
只需在頂端加入一行 Code 便可以

SuperCar.prototype = new Car;
function SuperCar(){
var hp;

this.getHP = function(){
return hp;
}

this.setHP = function(aHP){
hp = aHP;
}
}
請緊記 new Car; 不是 new Car();
沒有括號的

創造 SuperCar 的實體
因為 SuperCar 了 Car
所以 Car 的 function 也可以用到

var superCar = new SuperCar().init();
superCar.setPrice(7000000);
superCar.setName("My Super Car");
superCar.setHP(600);
alert(superCar.getName());
alert(superCar.getHP());

SuperCar 要加 10% 的價錢
但普通的 Car 不需要加 10% 的價錢
所以重寫 setPrice 這個 function

SuperCar.prototype = new Car;
function SuperCar(){
var self = this;
var hp;

var parent = {
setPrice : self.setPrice
};

this.getHP = function(){
return hp;
}

this.setHP = function(aHP){
hp = aHP;
}

this.setPrice = function(price){
parent.setPrice(price * 1.1);
}
}
SuperCar 繼承了 Car
SuperCar 擁有 Car 的 function 和 variable (變數)
SuperCar 可以 Re-write (複寫) Car 的 function
在 Re-write (複寫) 之前最好先將 Car 的被 Re-write (複寫) function 放進 variable (變數) 內
因為 javascript 沒有 java 的 super
SuperCar 根本不知自己繼承了其他 Class
所以最好將 function 記下
如果沒有將 Car 的 setPrice 記下
而在 setPrice 內 call setPrice
會發生無限 Recursion (循環)
就像這樣

SuperCar.prototype = new Car;
function SuperCar(){
var self = this;
var hp;

this.getHP = function(){
return hp;
}

this.setHP = function(aHP){
hp = aHP;
}

this.setPrice = function(price){
self.setPrice(price * 1.1);
}
}

可以試試看會發生什麼事


Javascript 的 Class 也可實現多重繼承

SuperCar.prototype = new Car;
SuperCar.prototype = new Car2;
SuperCar.prototype = new Car3;
function SuperCar(){
var hp;

this.getHP = function(){
return hp;
}

this.setHP = function(aHP){
hp = aHP;
}
}

但要注意一點
Car2 會覆蓋了 Car 的 function
而 Car3 會覆蓋了 Car 和 Car2 的 function
就好像一層一層蓋上去一樣

相關書籍: Object-Oriented JavaScript: Create scalable, reusable high-quality JavaScript applications and librariesObject-oriented Data Structures Using JavaJavaScript Objects