JavaScript的物件導向
JavaScript的物件
物件是JavaScript的一種資料型別。物件可以看成是屬性的無序集合,每個屬性都是一個鍵值對,屬性名是字串,因此可以把物件看成是從字串到值的對映。這種資料結構在其他語言中稱之為“雜湊(hash)”、“字典(dictionary)”、“關聯陣列(associative array)”等。
原型式繼承:物件不僅僅是字串到值的對映,除了可以保持自有的屬性,JavaScript物件還可以從一個稱之為原型的物件繼承屬性,物件的方法通常是繼承的屬性,這是JavaScript的核心特徵。
JavaScript物件是動態的—可以新增屬性也可以刪除屬性,但是他們常用來模擬靜態以及靜態型別語言中的“結構體”
建立物件
1、物件直接量
建立物件最簡單的方式就是在JavaScript程式碼中使用物件直接量。
var book = {
"main title" : `guide` , //屬性名字裡有空格,必須加引號
"sub-title" : `JS` , //屬性名字裡有連字元,必須加引號
for : `development` , //for是關鍵字,不過從ES5開始,作為屬性名關鍵字和保留字可以不加引號
author: {
firstname: `David` , //這裡的屬性名就都沒有引號
surname: `Flanagan`
}
}
|
注意: 從ES5開始,物件直接量中的最後一個屬性後的逗號將被忽略。
擴充套件: [JavaScript中的關鍵字和保留字]
如果你想學習前端,可以來這個Q群,首先是291,中間是851,最後是189,裡面可以學習和交流,也有資料可以下載。
2、通過new建立物件
new 運算子建立並初始化一個新物件。關鍵字new後跟一個函式呼叫。這裡的函式稱做建構函式(constructor),建構函式用以初始化一個新建立的物件。JavaScript中的資料型別都包含內建的建構函式。
var o = new Object(); //建立一個空物件,和{}一樣。
var arr = new Array(); //建立一個空陣列,和[]一樣。
|
擴充套件 1:new
new 是一個一元運算子,專門運算函式的。new後面呼叫的函式叫做建構函式,建構函式new的過程叫做例項化。
當new去呼叫一個函式 : 這個時候函式中的this就指向建立出來的物件,而且函式的的返回值直接就是this(隱式返回)
有一個預設慣例就是建構函式的名字首字母大寫。
注意:
當return的時候,如果是後面為簡單型別,那麼返回值還是這個物件;
如果return為物件型別,那麼返回的就是return後面的這個物件。
擴充套件 2:基本型別和物件型別(複雜型別)的區別
賦值:
基本型別 : 賦值的時候只是值的複製
物件型別 : 賦值不僅是值的複製,而且也是引用的傳遞(可以理解為記憶體地址)可以理解為賦址。
比較相等
基本型別 : 值相同就可以
物件型別 : 值和引用都相同才行
擴充套件 3:原型 prototype
每一個JavaScript物件(null除外)都和另一個物件相關聯,這個物件就是原型,每一個物件都從原型繼承屬性。
3、Object.create()
Object.create() 這個方法是ES5定義的,它建立一個新物件,其中第一個引數是這個物件的原型。第二個引數是可選引數,用以對物件屬性進行進一步描述。
可以通過傳入引數 null 建立一個沒有原型的新物件,不過這個新物件不會繼承任何東西,甚至不包括基礎方法。
var o = Object.create(null); //o不會繼承任何屬性和方法,空空的。
如果想建立一個普通的空物件,需要傳入Object.prototype
var o = Object.create(Object.prototype); //o相當於{}
物件屬性的獲取和設定
可以通過點(.)或方括號([])運算子來獲取和設定屬性的值。
var author = book.author;
var title = book[ "main title" ];
|
在JavaScript中能用 . 連線的都可以用 []連線。有很多 . 運算子不能用的時候,就需要用[]代替。
1、在屬性名可變的情況下用[]
function getAttr (obj, attr) {
console.log(obj[attr])
} |
2、屬性名有空格或者連字元等時用[]
var title = book[ "main title" ];
|
刪除屬性
delete運算子可以刪除物件的屬性。
delete只是斷開屬性和宿主物件的聯絡,而不會去操作屬性中的屬性,如果刪除的屬性是個物件,那麼這個物件的引用還是存在的。
var a = {b:{c:1}};
var b = a.b;
console.log(b.c); // 1
console.log(a.b); // {c:1}
delete a.b;
console.log(b.c); // 1
console.log(a.b); //undefined
|
delete只能刪除自有屬性,不能刪除繼承屬性。
返回值
返回值為true
當delete表示式刪除成功或沒有任何副作用(比如刪除不存在的屬性),或者delete後不是一個屬性訪問表示式,delete會返回 true ;
var a = {b:{c:1}};
console.log( delete a.b);
console.log( delete a.b);
console.log( delete a.toString);
console.log( delete 1);
以上都會列印 true
|
返回值為false
delete不能刪除那些可配置性為false的屬性,例如某些內建物件的屬性是不可配置的,通過變數宣告和函式宣告建立的全域性物件的屬性。
var a = {};
Object.defineProperty(a, `b` ,{
value:1,
configurable: false // 設定為不可配置
}) console.log( delete a.b)
console.log( delete Object.prototype)
var x = 1;
console.log( delete this .x);
console.log( delete x)
以上列印都為 false
|
檢測屬性
in 運算子
in 運算子的左側是屬性名(字串),右側是物件。如果物件的自有屬性或繼承屬性中包含這個屬性則返回true。
var a = {b:1};
console.log( `a` in window); // true 宣告的全域性變數`a`是window的屬性
console.log( `b` in a); // true `b`是a的屬性
console.log( `toString` in a); // true a繼承了toString屬性
console.log( `c` in a); // false `c`不是a的屬性
|
跟in運算子類似的,還可以用”!==”判斷一個屬性是否是undefined,但是有一種場景只能使用in運算子,in可以區分不存在的屬性和存在但值為undefined的屬性。
var a = {b:undefined};
console.log(a.b !== undefined); //false
console.log(a.c !== undefined); //false
console.log( `b` in a); //true
console.log( `c` in a); //false
|
hasOwnProperty
物件的hasOwnProperty()方法用來檢測給定的名字是否是物件的自有屬性。對於繼承屬性它將返回false
var a = {b:1};
console.log(a.hasOwnProperty( `b` )); //true
console.log(a.hasOwnProperty( `c` )); //false
console.log(a.hasOwnProperty( `toString` )); //false toString是繼承屬性
|
propertyIsEnumerable
物件的propertyIsEnumerable()方法只有檢測到是自身屬性(不包括繼承的屬性)且這個屬性的可列舉性為true時它才返回true。
var a = {b:1};
console.log(a.propertyIsEnumerable( `b` ));
console.log(a.propertyIsEnumerable( `toString` ));
|
包裝物件
當使用原始型別的值(string、number、boolean),在呼叫對應屬性和方法的時候,內部會自動轉成對應的物件。隱式建立的這個物件,就成為包裝物件。
基本型別都有自己對應的包裝物件 : String Number Boolean
包裝物件的特點
隱式建立物件後,可以呼叫對應的屬性和方法
使用後,立馬銷燬,所以不能給原始型別的值新增屬性和方法
其過程舉例:str.substring – > new String(1234) – > 找到String的substring -> 將new String銷燬
如果你想學習前端,可以來這個Q群,首先是291,中間是851,最後是189,裡面可以學習和交流,也有資料可以下載。
物件方法和屬性的彙總
Object靜態方法
- Object.assign()
- Object.create()
- Object.defineProperty()
- Object.defineProperties()
- Object.entries()
- Object.preventExtensions()
- Object.isExtensible()
- Object.seal()
- Object.isSealed()
- Object.freeze()
- Object.isFrozen()
- Object.keys()
- Object.values()
- Object.getPrototypeOf()
- Object.getOwnPropertyNames()
- Object.getOwnPropertyDescriptor()
- Object.getOwnPropertyDescriptors()
Object的例項方法(定義在Object.prototype上的)
- Object.prototype.hasOwnProperty()
- Object.prototype.isPrototypeOf()
- Object.prototype.propertyIsEnumerable()
- Object.prototype.toString()
- Object.prototype.valueOf()
物件導向
編碼思想
兩種程式設計方式:
(1)、程式導向
(2)、物件導向
兩者的區別:
程式導向:關注實現過程和每一步的實現細節。
物件導向:關注特徵和功能。
物件導向程式設計
通俗點,用物件的思想寫程式碼就是物件導向程式設計。
基本特徵
1、抽象:抓住核心問題(簡單理解為抽出像的部分;將相同或表現與問題相關特徵的內容提取出來。)
其核心:抽出、抽離,將相同的部分(可能會維護、會迭代、會擴充套件)的程式碼抽離出來形成一類
2、封裝:就是將類的屬性包裝起來,不讓外界輕易知道它內部的具體實現;只提供對外介面以供呼叫
3、繼承:從已有物件上繼承出新的物件
4、多型:一個物件的不同形態
物件導向的好處
1、程式碼的層次結構更清晰
2、更容易複用
3、更容易維護
4、更容易擴充套件
物件導向相關的屬性和概念
__proto__
屬性原型鏈,例項物件與原型之間的連線,叫做原型鏈。
物件身上只有 proto 建構函式身上有prototype也有 proto
constructor
返回建立例項物件的建構函式的引用,每個原型都會自動新增constructor屬性,for..in..遍歷原型是找不到這個屬性的。
var a = new A();
console.log(a.constructor == A) //true
|
hasOwnProperty
可以用來判斷某屬性是不是這個建構函式的內部屬性(不包括繼承的)
語法: obj.hasOwnProperty(prop) 返回Boolean
function A (){
this .b = 1;
} var a = new A();
console.log(a.hasOwnProperty( `b` )); //列印true
console.log(a.hasOwnProperty( `toString` )); //toString是繼承屬性 列印 false
console.log(a.hasOwnProperty( `hasOwnProperty` )); //同上,列印false
|
nstanceof
二元運算子,用來檢測一個物件在其原型鏈中是否存在一個建構函式的 prototype 屬性。
語法: object instanceof constructor 即檢測 constructor.prototype 是否存在於引數 object 的原型鏈上。
// 定義建構函式 function C(){}
function D(){}
var o = new C();
o instanceof C; // true,因為 Object.getPrototypeOf(o) === C.prototype
o instanceof D; // false,因為 D.prototype不在o的原型鏈上
o instanceof Object; // true,因為Object.prototype.isPrototypeOf(o)返回true
C.prototype instanceof Object // true,同上
|
toString
返回一個表示該物件的字串
作用:
1、進行數字之間的進位制轉換
例如: var num = 255;
alert( num.toString(16) ); //結果就是`ff`
|
2、利用toString做型別的判斷
例如: var arr = [];
alert( Object.prototype.toString.call(arr) == `[object Array]` ); 彈出 true
Object.prototype.toString.call() 得到是類似於 `[object Array]` `[object Object]`
|
物件導向的寫法歷程
1、原始模式
假如我們有一個物件是狗的原型,這個原型有“名字”和“顏色”兩個屬性。
var Dog = {
name: ”,
color: ”
}
根據這個原型物件,我們要生成一個例項物件如下
var hashiqi = {}; //建立空物件,之後根據原型物件的相應屬性賦值
hashiqi.name = `hashiqi` ;
hashiqi.color = `blackandwhite` ;
|
缺點:
1、如果要生成多個例項物件,要重複寫多次。
2、例項和原型之間沒有聯絡。
2、工廠模式
上面原始模式有一個缺點是要很麻煩的寫很多重複的程式碼,我們可以寫一個函式來解決程式碼重複的問題。
function Dog(name, color) {
var obj = {};
obj.name = name;
obj.color = color;
return obj;
} var hashiqi = Dog( `hashiqi` , `blackandwhite` );
var jinmao = Dog( `jinmao` , `yellow` );
|
這種方式只是解決了程式碼重複的問題,但是生成的例項跟原型還是沒有聯絡,而且hashiqi和jinmao也沒有聯絡,不能反映出他們是同一個原型物件的例項。
3、建構函式模式
用來建立物件的函式,叫做建構函式,其實就是一個普通函式,但是預設函式名首字母大寫,對建構函式使用new運算子,就能生成例項,並且this變數會繫結在例項物件上。
function Dog(name, color) {
this .name = name;
this .color = color;
} var hashiqi = new Dog( `hashiqi` , `blackandwhite` );
var jinmao = new Dog( `jinmao` , `yellow` );
console.log(hashiqi.name); //hashiqi
console.log(jinmao.name); //jinmao
|
hasiqi 和 jinmao有一個共同的建構函式 hashiqi.constructor === jinmao.constructor 是true
有以下幾種方法可以驗證原型物件與例項物件的關係:
hashiqi instanceof Dog; // true
Object.getPrototypeOf(hashiqi) === Dog.prototype // true
Dog.prototype.isPrototypeOf(hashiqi) // true
|
缺點:
建構函式解決了程式碼重複和例項與原型之間的聯絡,但是存在一個浪費記憶體的問題。比如遠行物件有一些不變的屬性和通用的方法,這樣沒生成一個例項,都必須為重複的東西多佔一些記憶體。
擴充套件
我們可以嘗試實現new運算子的邏輯如下:
function New(func) {
var obj = {};
//判斷建構函式是否存在原型,如果有例項的__proto__屬性就指向建構函式的prototype
if (func.prototype !== undefined) {
obj.__proto__ = func.prototype;
}
// 模擬出建構函式內部this指向例項的過程,注意,我們會拿到建構函式的返回值
var res = func.apply(obj, Array.from(arguments).slice(1));
// 正常建構函式是不需要顯式宣告返回值的,預設的返回值是生成的例項,但是一旦在建構函式中return 一個不是物件或者函式,就會改變建構函式的預設的返回值,其他的型別是不變的
if ( typeof res === `object` && res !== null || typeof res === `function` ) {
return res;
}
return obj;
} var taidi = New(Dog, `taidi` , `gray` );
|
注意:
正常的建構函式是不需要自己寫return 的,如果寫了,當return的時候,如果是後面為簡單型別,那麼返回值還是建構函式生成的例項。如果return為物件型別或者函式,那麼返回的就是return後面的這個物件或者函式。
4、prototype模式
每一個建構函式都有 prototype 屬性,這個屬性指向的是一個物件,這個物件的所有屬性和方法,都會被建構函式的例項繼承。
基於這個屬性,我們就可以有選擇性的將一些通用的屬性和方法定義到 prototype 上,每一個通過 new 生成的例項,都會有一個 proto 屬性指向建構函式的原型即 prototype ,這樣我們定義到建構函式原型物件的屬性和方法,就會被每一個例項訪問到,從而變成公用的屬性和方法。
function Dog(name, color) {
this .name = name;
this .color = color;
} Dog.prototype.say = function () {
console.log( "汪汪" );
} var hashiqi = new Dog( `hashiqi` , `blackandwhite` );
var jinmao = new Dog( `jinmao` , `yellow` );
hashiqi.say(); // 汪汪
jinmao.say(); // 汪汪
console.log(hashiqi.say === jinmao.say); // true
|
注意:當例項物件和原型物件有相同的屬性或者方法時,會優先訪問例項物件的屬性或方法。
物件導向的繼承
1、建構函式內部的屬性和方法繼承
使用call或apply方法,將父物件的建構函式繫結在子物件上。
//父類 function Animal() {
this .species = `動物` ;
} //子類 function Dog(name, color) {
Animal.call( this );
this .name = name;
this .color = color;
} var hashiqi = new Dog( `hashiqi` , `blackandwhite` );
console.log(hashiqi.species); //動物
|
2、prototype相關的繼承
子類的prototype指向父類生成例項
function Animal() {};
Animal.prototype.species = `動物` ;
function Dog(name, color) {
this .name = name;
this .color = color;
} Dog.prototype = new Animal();
//只要是prototype被完全覆蓋,都得重寫constructor。 Dog.prototype.constructor = Dog; var hashiqi = new Dog( `hashiqi` , `blackandwhite` );
|
缺點: 每一次繼承都得生成一個父類例項,比較佔記憶體。
利用空物件作為中介
function Animal() {}
Animal.prototype.species = `動物` ;
function Dog(name, color) {
this .name = name;
this .color = color;
} //Middle生成的是空例項(除了__proto__),幾乎不佔記憶體 function Middle() {}
Middle.prototype = Animal.prototype; Dog.prototype = new Middle();
Dog.prototype.constructor = Dog; var hashiqi = new Dog( `hashiqi` , `blackandwhite` );
console.log(hashiqi.species); |
幾個月前在 CSDN 面試的時候,我說了這種繼承方式,面試官就糾結這樣修改子類的prototype不會影響父類麼?是真的不會影響的,因為子類的prototype是指向Middle建構函式生成的例項,如果真的有心要改,得Dog.prototype.proto這麼著來改。
Object.create()
function Animal() {}
Animal.prototype.species = `動物` ;
function Dog(name, color) {
this .name = name;
this .color = color;
} Dog.prototype = Object.create(Animal.prototype,{ constructor: {
value: Dog
}
}) var hashiqi = new Dog( `hashiqi` , `blackandwhite` );
console.log(hashiqi.species); //動物
|
3、拷貝繼承
淺拷貝
function Animal() {}
Animal.prototype.species = `動物` ;
function Dog(name, color) {
this .name = name;
this .color = color;
} function extend(child, parent) {
var c = child.prototype;
var p = parent.prototype;
for (key in p) {
c[key] = p[key]
}
} extend(Dog, Animal); var hashiqi = new Dog( `hashiqi` , `blackandwhite` );
console.log(hashiqi.species) // 動物
|
深拷貝
function deepCopy(parent, child) {
var child = child || {};
for (key in parent) {
if ( typeof parent[key] === `object` ) {
child[key] = parent[key].constructor === Array?[]:{};
deepCopy(parent[key],child[key])
} else {
child[key] = parent[key];
}
}
return child;
} |
ES6的物件導向
上面所說的是JavaScript語言的傳統方法,通過建構函式,定義並生成新的物件。
ES6中提供了更接近傳統語言的寫法,引入了Class(類)的概念,通過class關鍵字,可以定義類。
語法
ES6的類完全可以看成是建構函式的另外一種寫法。
var method = `say` ;
class Dog { constructor (name,color) {
this .name = name;
this .color = color;
}
//注意,兩個屬性之間跟物件不同,不要加逗號,並且類的屬性名可以使用變數或者表示式,如下
[method] () {
console.log( `汪汪` );
}
} console.log( typeof Dog); // function 類的資料型別就是函式
console.log(Dog === Dog.prototype.constructor); // true 類本身就是建構函式
|
既然是建構函式,所以在使用的時候,也是直接對類使用new命令,跟建構函式的用法完全一致。
var hashiqi = new Dog( `hashiqi` , `blackandwhite` );
console.log(hashiqi.color); // blackandwhite
//上面採用表示式宣告的類的屬性可以用一下兩種方式呼叫 hashiqi[method](); // 汪汪
hashiqi.say(); // 汪汪
|
注意:
1、先宣告定義類,再建立例項,否則會報錯
class 不存在變數提升,這一點與ES5的建構函式完全不同
new Dog( `hashiqi` , `blackandwhite` )
class Dog { constructor (name,color) {
this .name = name;
this .color = color;
}
} //Uncaught ReferenceError: Dog is not defined //上面程式碼,Dog類使用在前,定義在後,因為ES6不會把類的宣告提升到程式碼頭部,所以報錯Dog沒有定義。 |
2、必須使用new關鍵字來建立類的例項物件
類的建構函式,不使用new是沒法呼叫的,會報錯。 這是它跟普通建構函式的一個主要區別,後者不用new也可以執行。
class Dog { constructor (name,color) {
this .name = name;
this .color = color;
}
} Dog(); // Uncaught TypeError: Class constructor Dog cannot be invoked without `new`
|
3、定義“類”的方法的時候,前面不需要加上function這個關鍵字,直接把函式定義放進去了就可以了。並且,方法之間不需要逗號分隔,加了會報錯。
屬性概念
constructor 建構函式
構造方法constructor是一個類必須要有的方法,預設返回例項物件;建立類的例項物件的時候,會呼叫此方法來初始化例項物件。如果你沒有編寫constructor方法,執行的時候也會被加上一個預設的空的constructor方法。
constructor方法是必須的,也是唯一的,一個類體不能含有多個constructor構造方法。
class Dog { constructor (name,color) {
this .name = name;
this .color = color;
}
//定義了兩個constructor,所以會報錯
constructor () {
}
} new Dog( `hashiqi` , `blackandwhite` )
//Uncaught SyntaxError: A class may only have one constructor |
Class表示式
與函式一樣,類可以使用表示式的形式定義。
const Hashiqi = class Dog { constructor (name,color) {
this .name = name;
this .color = color;
}
getName () {
//此處的Dog就是Dog建構函式,在表示式形式中,只能在建構函式內部使用
console.log(Dog.name);
}
} var hashiqi = new Hashiqi( `hashiqi` , `blackandwhite` ); // 真正的類名是Hashiqi
var jinmao = new Dog( `jinmao` , `yellow` ); // 會報錯,Dog沒有定義
|
通常我們的表示式會寫成如下,省略掉類後面的名稱
const Hashiqi = class { constructor (name,color) {
this .name = name;
this .color = color;
}
} var hashiqi = new Hashiqi( `hashiqi` , `blackandwhite` );
|
例項方法和靜態方法
例項化後的物件才可以呼叫的方法叫做例項方法。
直接使用類名即可訪問的方法,稱之為“靜態方法”
類相當於例項的原型,所有在類中定義的方法,都會被例項繼承。如果在一個方法前,加上static關鍵字,就表示該方法不會被例項繼承,而是直接通過類來呼叫,這就稱為“靜態方法”。
class Dog { constructor (name,color) {
this .name = name;
this .color = color;
}
static say () {
console.log( `汪汪` );
}
} Dog.say(); //汪汪
|
靜態方法和例項方法不同的是:靜態方法的定義需要使用static關鍵字來標識,而例項方法不需要;此外,靜態方法通過類名來的呼叫,而例項方法通過例項物件來呼叫。
類的繼承
extends
類之間可以通過extends關鍵字實現繼承,這比ES5的通過修改原型鏈實現繼承,要清晰和方便很多。
class Dog extends Animal{} |
extends的繼承目標
extends關鍵字後面可以跟多種型別的值,有三種特殊情況
1、子類繼承Object類
class A extends Object {} console.log(A.__proto__ === Object) //true
console.log(A.prototype.__proto__ == Object.prototype) //true
//這種情況下,A其實就是建構函式Object的複製,A的例項就是Object的例項。 |
2、不存在繼承
class A {} console.log(A.__proto__ === Function.prototype) // true
console.log(A.prototype.__proto__ === Object.prototype) // true
//這種情況下,A作為一個基類(即不存在任何繼承),就是一個普通函式,所以直接繼承Funciton.prototype。 //但是,A呼叫後返回一個空物件(即Object例項),所以A.prototype.__proto__指向建構函式(Object)的prototype屬性。 |
3、子類繼承null
class A extends null {}
console.log(A.__proto__ === Function.prototype) //true
console.log(A.prototype) //只有一個constructor屬性,沒有__proto__屬性
這種情況與第二種情況非常像。A也是一個普通函式,所以直接繼承Funciton.prototype。 但是,A呼叫後返回的物件不繼承任何方法,所以沒有__proto__這屬性 |
super
uper這個關鍵字,既可以當作函式使用,也可以當作物件使用。
1、super作為函式呼叫時,代表父類的建構函式。作為函式時,super()只能用在子類的建構函式之中,用在其他地方就會報錯。
2、super作為物件時,在普通方法中,指向父類的原型物件;在靜態方法中,指向父類。
class Animal { constructor (name) {
this .name = name;
this .species = `動物` ;
}
say (){
return this .species;
}
} class Dog extends Animal{ constructor (name, color) {
// 只要是自己在子類中定義constructor,必須呼叫super方法,否則新建例項會報錯
//super作為函式呼叫,只能用在子類的constructor中
super (name);
this .color = color;
}
getInfo () {
//普通方法中,super指向父類的原型物件
console.log( super .say()+ `: ` + this .name + `,` + this .color);
}
} var hashiqi = new Dog( `hashiqi` , `blackandwhite` );
hashiqi.getInfo() //動物:hashiqi,balckandwhite
|
注意:
1、子類必須在constructor方法中呼叫super方法,否則新建例項時會報錯。這是因為子類沒有自己的this物件,而是繼承父類的this物件,然後對其進行加工。如果不呼叫super方法,子類就得不到this物件。
2、在子類的普通方法中,由於super指向父類的原型物件,所以定義在父類例項上的方法或屬性,是無法通過super呼叫的。
3、使用super的時候,必須顯式指定是作為函式、還是作為物件使用,否則會報錯。
相關文章
- JavaScript 物件導向JavaScript物件
- JavaScript 的物件導向(OO)JavaScript物件
- 更多物件導向的JavaScript物件JavaScript
- 初探 JavaScript 物件導向JavaScript物件
- JavaScript中的物件導向----類JavaScript物件
- 全面理解物件導向的 JavaScript物件JavaScript
- JavaScript物件導向—物件的建立和操作JavaScript物件
- 【讀】JavaScript之物件導向JavaScript物件
- JavaScript7:物件導向JavaScript物件
- JavaScript物件導向入門JavaScript物件
- JavaScript 物件導向初步理解JavaScript物件
- JavaScript物件導向精要(二)JavaScript物件
- JavaScript 物件導向精要(一)JavaScript物件
- JavaScript模擬物件導向JavaScript物件
- javascript:物件導向的程式設計JavaScript物件程式設計
- 《JavaScript物件導向精要》之六:物件模式JavaScript物件模式
- 《JavaScript物件導向精要》之三:理解物件JavaScript物件
- JavaScript 物件導向實戰思想JavaScript物件
- JavaScript物件導向詳解(原理)JavaScript物件
- Javascript物件導向與繼承JavaScript物件繼承
- JavaScript學習2:物件導向JavaScript物件
- Javascript 物件導向程式設計JavaScript物件程式設計
- DEJAVU庫:讓JavaScript物件導向JavaScript物件
- JavaScript物件導向—繼承的實現JavaScript物件繼承
- JavaScript 中的物件導向程式設計JavaScript物件程式設計
- 物件導向的JavaScript程式設計 (轉)物件JavaScript程式設計
- 物件導向-物件導向思想物件
- JavaScript 遊戲中的物件導向的設計JavaScript遊戲物件
- JavaScript遊戲中的物件導向的設計JavaScript遊戲物件
- javascript的物件導向的繼承實現JavaScript物件繼承
- JavaScript高階:JavaScript物件導向,JavaScript內建物件,JavaScript BOM,JavaScript封裝JavaScript物件封裝
- JavaScript物件導向名詞詳解JavaScript物件
- JavaScript物件導向程式設計理解!JavaScript物件程式設計
- 1.16 JavaScript7:物件導向JavaScript物件
- 《JavaScript物件導向精要》系列文章JavaScript物件
- Javascript實現物件導向繼承JavaScript物件繼承
- Javascript 物件導向程式設計(一)JavaScript物件程式設計
- Javascript 物件導向程式設計(二)JavaScript物件程式設計