這一次我們深入的學習一下JavaScript面向對象技術,在學習之前,必要的說明一下一些面向對象的一些術語。這也是所有面對對象語言所擁有的共同點。有這樣幾個面向對象術語:
對象
ECMA-262把對象(object)定義為“屬性的無序集合,每個屬性存放一個原始值、對象或函數”。嚴格來說,這意味著對象是無特定順序的值的數組。盡管ECMAScript如此定義對象,但它更通用的定義是基于代碼的名詞(人、地點或事物)的表示。
類
每個對象都由類定義,可以把類看做對象的配方。類不僅要定義對象的接口(interface)(開發者訪問的屬性和方法),還要定義對象的內部工作(使屬性和方法發揮作用的代碼)。編譯器和解釋程序都根據類的說明構建對象。
實例
程序使用類創建對象時,生成的對象叫作類的實例(instance)。對類生成的對象的個數的唯一限制來自于運行代碼的機器的物理內存。每個實例的行為相同,但實例處理一組獨立的數據。由類創建對象實例的過程叫做實例化(instantiation)。
在前面的章節我們提到過,ECMAScript并沒有正式的類。相反,ECMA-262把對象定義描述為對象的配方。這是?ECMAScript邏輯上的一種折中方案,因為對象定義實際上是對象自身。即使類并不真正存在,我們也把對象定義叫做類,因為大多數開發者對此術語更熟悉,而且從功能上說,兩者是等價的。
使用預定義對象只是面向對象語言的能力的一部分,它真正強大之處在于能夠創建自己專用的對象。
ECMAScript?擁有很多創建對象的方法。
### 一,原始方式
因為對象的屬性可以在對象創建后動態定義,所有許多開發者都在JavaScript 最初引入時編寫類似下面的代碼:
~~~
var Car = new Object();
Car.color = "blue";
Car.doors = 4;
Car.mpg = 25;
Car.showColor = function() {
return this.color;
};
document.write(Car.showColor());//輸出:blue
~~~
在上面的代碼中,創建對象Car。然后給它設置幾個屬性:它的顏色是藍色,有四個門,每加侖油可以跑 25 英里。最后一個屬性實際上是指向函數的指針,意味著該屬性是個方法。執行這段代碼后,就可以使用對象Car。不過這里有一個問題,就是可能需要創建多個Car的實例,這樣就造成了我們會重復許多類似的代碼,這樣會很麻煩。
### 二,工廠方式
要解上述的多個類似對象聲明的問題,開發者創造了能創建并返回特定類型的對象的工廠方式。這種方式就是為了解決實例化對象產生大量重復的問題。
(1)無參數的工廠方式
例如,函數createCar()可用于封裝前面列出的創建Car對象的操作:
~~~
function createCar() {
var TempCar = new Object();
TempCar.color = "blue";
TempCar.doors = 4;
TempCar.mpg = 25;
TempCar.showColor = function() {
return this.color;
};
return TempCar;
};
var Car1 = createCar();
var Car2 = createCar();
document.write(Car1.showColor()+"<br/>");//輸出:blue
document.write(Car2.showColor());//輸出:blue
~~~
在這里,第一個例子中的所有代碼都包含在createCar()函數中。此外,還有一行額外的代碼,返回TempCar 對象作為函數值。調用此函數,將創建新對象,并賦予它所有必要的屬性,復制出一個我們在前面說明過的Car對象。
因此,通過這種方法,我們可以很容易地創建Car對象的兩個版本(Car1和 Car2),它們的屬性完全一樣。
(2)有參數的工廠方式
我們還可以修改createCar()函數,給它傳遞各個屬性的默認值,而不是簡單地賦予屬性默認值:
~~~
function createCar(Color,Doors,Mpg) {
var TempCar = new Object();
TempCar.color = Color;
TempCar.doors = Doors;
TempCar.mpg = Mpg;
TempCar.showColor = function() {
return this.color;
};
return TempCar;
};
var Car1 = createCar("red",4,23);
var Car2 = createCar("blue",3,25);
document.write(Car1.showColor()+"<br/>");//輸出:red
document.write(Car2.showColor());//輸出:blue
~~~
給createCar()函數加上參數,即可為要創建的Car對象的color、doors 和mpg屬性賦值。這使兩個對象具有相同的屬性,卻有不同的屬性值。
工廠方式解決了重復實例化的問題,但是還是有一個問題,那就是前面的例子中,每次調用函數createCar(),都要創建新函數showColor(),意味著每個對象都有自己的 showColor()版本。而事實上,每個對象都共享同一個函數。
有些開發者在工廠函數外定義對象的方法,然后通過屬性指向該方法,從而避免這個問題:
~~~
function showColor() {
return this.color;
};
function createCar(Color,Doors,Mpg) {
var TempCar = new Object();
TempCar.color = Color;
TempCar.doors = Doors;
TempCar.mpg = Mpg;
TempCar.showColor = showColor;
return TempCar;
};
var Car1 = createCar("red",4,23);
var Car2 = createCar("blue",3,25);
document.write(Car1.showColor()+"<br/>");//輸出:red
document.write(Car2.showColor());//輸出:blue
~~~
在上面這段重寫的代碼中,在函數 createCar()之前定義了函數 showColor()。在createCar()內部,賦予對象一個指向已經存在的 showColor() 函數的指針。從功能上講,這樣解決了重復創建函數對象的問題;但是從語義上講,該函數不太像是對象的方法。所有這些問題都引發了開發者定義的構造函數的出現。
### 三,構造函數方式
創建構造函數就像創建工廠方式的函數一樣容易。第一步選擇構造函數的名字。根據慣例,這個名字的首字母大寫,以使它與首字母通常是小寫的變量名分開。除了這點不同,構造函數看起來很像工廠方式的函數。請看下面的例子:
~~~
function Car(Color,Doors,Mpg) {
this.color = Color;
this.doors = Doors;
this.mpg = Mpg;
this.showColor = function() {
return this.color;
};
};
var Car1 = new Car("red",4,23);
var Car2 = new Car("blue",3,25);
document.write(Car1.showColor()+"<br/>");//輸出:red
document.write(Car2.showColor());//輸出:blue
~~~
下面為您解釋上面的代碼與工廠方式的差別。首先在構造函數內沒有創建對象,而是使用this關鍵字。使用new運算符構造函數時,在執行第一行代碼前先創建一個對象,只有用this才能訪問該對象。然后可以直接賦予this屬性,默認情況下是構造函數的返回值(不必明確使用 return 運算符)。現在,用new運算符和對象名Car創建對象,就更像ECMAScript 中一般對象的創建方式了。
就像工廠方式的函數,構造函數會重復生成函數,為每個對象都創建獨立的函數版本。不過,與工廠方式的函數相似,也可以用外部函數重寫構造函數,同樣地,這么做語義上無任何意義。這正是下面要講的原型方式的優勢所在。在下篇博客會詳細的分析面向對象的原型方式以及其他綜合的方式。
- 前言
- HTML學習1:Dreamweaver8的安裝
- HTML學習2:初識HTML
- HTML學習3:常用標簽之文本標簽
- HTML學習4:常用標簽之列表標簽
- HTML學習5:常用標簽之圖像標簽
- HTML學習6:常用標簽之超鏈接標簽
- HTML學習7:常用標簽之表格標簽
- HTML學習8:常用標簽之框架標簽
- HTML學習9:常用標簽之表單標簽
- HTML學習10:表單格式化
- HTML學習11:HTTP 方法
- HTML學習12:其他常見標簽之頭標簽
- HTML學習13:其他常見標簽之體標簽
- 輕松學習JavaScript一:為什么學習JavaScript
- 輕松學習JavaScript二:JavaScript語言的基本語法要求
- 輕松學習JavaScript三:JavaScript與HTML的結合
- 輕松學習JavaScript四:JS點擊燈泡來點亮或熄滅這盞燈的網頁特效映射出JS在HTML中作用
- 輕松學習JavaScript五:JavaScript的變量和數據類型
- 輕松學習JavaScript六:JavaScript的表達式與運算符
- 輕松學習JavaScript七:JavaScript的流程控制語句
- 輕松學習JavaScript八:JavaScript函數
- 輕松學習JavaScript九:JavaScript對象和數組
- 輕松學習JavaScript十:JavaScript的Date對象制作一個簡易鐘表
- 輕松學習JavaScript十一:JavaScript基本類型(包含類型轉換)和引用類型
- 輕松學習JavaScript十二:JavaScript基于面向對象之創建對象(一)
- 輕松學習JavaScript十二:JavaScript基于面向對象之創建對象(二)
- 輕松學習JavaScript十三:JavaScript基于面向對象之繼承(包含面向對象繼承機制)
- 輕松學習JavaScript十四:JavaScript的RegExp對象(正則表達式)
- 輕松學習JavaScript十五:JavaScript之BOM簡介
- 輕松學習JavaScript十六:JavaScript的BOM學習(一)
- 輕松學習JavaScript十七:JavaScript的BOM學習(二)
- 輕松學習JavaScript二十九:JavaScript中的this詳解
- CSS基礎學習一:CSS概述
- CSS基礎學習二:如何創建 CSS
- CSS基礎學習三:CSS語法
- CSS基礎學習四:元素選擇器
- CSS基礎學習五:類選擇器
- CSS基礎學習六:id選擇器
- CSS基礎學習七:屬性選擇器
- CSS基礎學習八:派生選擇器
- CSS基礎學習九:偽類
- CSS基礎學習十:偽元素
- CSS基礎學習十一:選擇器的優先級
- CSS基礎學習十二:CSS樣式
- CSS基礎學習十三:盒子模型
- CSS基礎學習十四:盒子模型補充之display屬性設置
- CSS基礎學習十五:盒子模型補充之外邊距合并
- CSS基礎學習十六:CSS盒子模型補充之border-radius屬性
- CSS基礎學習十七:CSS布局之定位
- CSS基礎學習十八:CSS布局之浮動
- CSS基礎學習十九:CSS布局之圖文混排,圖像簽名,多圖拼接和圖片特效
- DIV+CSS實操一:經管系網頁總體模塊布局
- DIV+CSS實操二:經管系網頁添加導航欄和友情鏈接欄
- DIV+CSS實操三:經管系網頁內容模塊添加標題欄和版權信息模塊
- DIV+CSS實操四:經管系網頁內容模塊內容添加(一)
- DIV+CSS實操五:經管系網頁內容模塊內容添加(二)
- DIV+CSS實操六:經管系網頁添加導航欄下拉菜單
- DIV+CSS實操七:中文系內容模塊控制文本不換行和超出指定寬度后用省略號代替
- JS中實現字符串和數組的相互轉化