/* 對(duì)象字面量 */
var empty_object = {};
var stooge = {
"first-name": "Jerome",
"last-name": "Howard"
};
var flight = {
airline: "Oceanic",
number: 815,
departure: {
IATA: "SYD",
time: "2004-09-22 14:55",
city: "Sydney"
},
arrival: {
IATA: "LAX",
time: "2004-09-23 10:55",
city: "Los Angeles"
}
};
/* 檢索 */
stooge["first=name"]; // "Joe"
flight.departure.IATA; // "SYD"
/* 檢索不存在將返回一個(gè) undefined 值 */
stooge["middle-name"]; // "undefined"
/* || 運(yùn)算符可以用來(lái)填充默認(rèn)值 */
var middle = stooge["middle-name"] || "(none)";
/* 嘗試檢索一個(gè) undefined 值將會(huì)導(dǎo)致TypeError 異常,可以通過(guò) && 運(yùn)算符避免 */
flight.equipment; // undefined
flight.equipment.model; // throw "TypeError"
flight.equipment && flight.equipment.model //undefined
/* 更新 */
stooge["first-name"] = "Jerome";
/* 擴(kuò)充屬性 */
stooge['middle-name'] = 'Lester';
stooge.nickname = 'Curly';
flight.equipment = {
medel: 'Boeing 777'
};
flight.status = 'overdue';
/* 引用 */
var x = stooge;
x.nickname = 'Curly';
var nick = stooge.nickname; // 因?yàn)?x 和 stooge 是指向同一個(gè)對(duì)象的引用,所以 nick 為 'Curly'
var a = {}, b = {}, c = {}; //a,b,c 每個(gè)都引用一個(gè)不同的空對(duì)象
a = b = c = {}; //a,b,c 都引用同一個(gè)空對(duì)象
/* 原型 */
/*
每個(gè)對(duì)象都連接到一個(gè)原型對(duì)象,并且它可以從中繼承屬性。所有通過(guò)對(duì)象字面量創(chuàng)建的對(duì)象都連接到
Object.prototype 這個(gè)JavaScript 中標(biāo)準(zhǔn)的對(duì)象。
當(dāng)你創(chuàng)建一個(gè)新對(duì)象時(shí),你可以選擇某個(gè)對(duì)象作為它的原型對(duì)象。JavaScript 提供的實(shí)現(xiàn)機(jī)制雜亂而
復(fù)雜,但其實(shí)它可以被明顯的簡(jiǎn)化。我們將給 Object 增加一個(gè) beget 方法。這個(gè) beget 方法創(chuàng)建
一個(gè)使用原對(duì)象作為其原型的新對(duì)象。
*/
if (typeof Object.beget !=== 'function') {
Object.beget = function(o) {
var F = function() {};
F.prototype = o;
return new F();
};
}
var anothor_stooge = Object.beget(stooge);
/*
原型連接在更新時(shí)是不起作用的。當(dāng)我們對(duì)某個(gè)對(duì)象做出改變時(shí),不會(huì)觸及到該對(duì)象的原型:
*/
anothor_stooge['first-name'] = 'Harry';
anothor_stooge['middle-name'] = 'Moses';
anothor_stooge.nickname = 'Moe';
/*
原型連接只有在檢索值的時(shí)候才被用到。如果我們嘗試去獲取對(duì)象的某個(gè)屬性值,且該對(duì)象沒(méi)有此屬性
名,那么 JavaScript 會(huì)嘗試著從原型對(duì)象中獲取屬性值。如果那個(gè)原型對(duì)象也沒(méi)有該屬性,那么再?gòu)?br /> 它的原型中尋找,依次類推,知道該過(guò)程最后到達(dá)終點(diǎn) Object.prototype。如果想要的屬性完全不存在
于原型鏈中,那么結(jié)果就是undefined值。這個(gè)過(guò)程稱為委托。
原型關(guān)系是一種動(dòng)態(tài)的關(guān)系。如果我們添加一個(gè)新的屬性到原型匯中,該屬性會(huì)立即對(duì)所有基于該原型
創(chuàng)建的對(duì)象可見(jiàn)。
*/
stooge.profession = 'actor';
anothor_stooge.profession; // 'actor'
/* 反射 */
/*
檢查對(duì)象并確定對(duì)象有什么屬性是很容易的事情,只要試著去檢索該屬性并驗(yàn)證取得的值。
typeof 操作符對(duì)確定屬性的類型很有幫助:
*/
typeof flight.number; // 'number'
typeof flight.status; // 'string'
typeof flight.arrival; // 'object'
typeof flight.manifest; // 'undefined'
/* 請(qǐng)務(wù)必注意原型鏈中任何屬性也會(huì)產(chǎn)生一個(gè)值 */
typeof flight.toString(); // 'function'
typeof flight.constructor; // 'function'
/*
有兩個(gè)方法去處理這些不需要的屬性。第一個(gè)是讓你的程序檢查并剔除函數(shù)值。一般來(lái)說(shuō),
做反射的目標(biāo)是數(shù)據(jù),因此你應(yīng)該意識(shí)到一些值可能會(huì)是函數(shù)。
另一個(gè)方法是使用 hasOwnProperty 方法,如果對(duì)象擁有獨(dú)有的屬性,它將返回 true 。
hasOwnProperty 方法不會(huì)檢查原型鏈。
*/
flight.hasOwnProperty('number'); //true
flight.hasOwnProperty('constructor'); //false
/* 枚舉 */
/*
for in 語(yǔ)句可用來(lái)遍歷一個(gè)對(duì)象中的所有屬性名。該枚舉過(guò)程將會(huì)列出所有的屬性——
包括函數(shù)和你可能不關(guān)心的原型中的屬性——所以有必要過(guò)濾掉那些你不想要的值。
最為常用的過(guò)濾器是 hasOwnProperty 方法,以及使用 typeof 來(lái)排除函數(shù):
*/
var name;
for(name in anothor_stooge) {
if (typeof anothor_stooge[name] !== 'function') {
document.writeln(name + ': ' + anothor_stooge[name]);
}
}
/*
屬性名出現(xiàn)的順序是不確定的,因此要對(duì)任何可能出現(xiàn)的順序有所準(zhǔn)備。如果你想要確保
屬性以特定的順序出現(xiàn),最好的辦法就是完全避免使用 for in 語(yǔ)句,而是創(chuàng)建一個(gè)數(shù)組,
在其中以正確的順序包含屬性名:
*/
var i;
var properties = [
'first-name', 'middle-name', 'last-name', 'profession'
];
for(i = 0; i < properties.length; i += 1) {
document.writeln(properties[i] + ': ' + anothor_stooge[properties[i]]);
}
/*
通過(guò)使用 for 而不是 for in,可以得到我們想要的屬性,而不用擔(dān)心可能發(fā)掘出原型鏈中
屬性,并且我們按正確的順序缺的它們的值。
*/
/* 刪除 */
/*
delete 運(yùn)算符可以用來(lái)刪除對(duì)象的屬性。它將會(huì)移除對(duì)象中確定包含的屬性。它不會(huì)觸及
原型鏈中的任何對(duì)象。
刪除對(duì)象的屬性可能會(huì)讓來(lái)自原型鏈中的屬性浮現(xiàn)出來(lái):
*/
anothor_stooge.nickname; // 'Moe'
// 刪除 anothor_stooge 的 nickname 屬性,從而暴露原型的 nickname 屬性
delete anothor_stooge.nickname;
anothor_stooge.nickname; // 'Curly'
/* 減少全局變量的污染 */
/*
JavaScript 可以很隨意地定義那些可保存所有的應(yīng)用資源的全局變量。不幸的是,全局變量削弱
了程序的靈活性,所以應(yīng)該避免。
最小化使用全局變量的一個(gè)方法是在你的應(yīng)用中只創(chuàng)建唯一一個(gè)全局變量:
*/
var MYAPP = {};
/*
該變量此時(shí)變成了你的應(yīng)用容器:
*/
MYAPP.stooge = {
"first-name": "Joe",
"last-name": "Howard"
};
MYAPP.flight = {
airline: "Oceanic",
number: 815,
departure: {
IATA: "SYD",
time: "2004-09-22 14:55",
city: "Sydney"
},
arrival: {
IATA: "LAX",
time: "2004-09-23 10:55",
city: "Los Angeles"
}
};
/*
只要把多個(gè)全局變量都整理在一個(gè)命名空間下,你將顯著降低與其他應(yīng)用程序,組件或類庫(kù)之間產(chǎn)生
糟糕的互相影響的可能性。你的程序也會(huì)變得更容易閱讀,因?yàn)楹苊黠@ MYAPP.stooge 指向的是頂層
結(jié)構(gòu)。
使用閉包來(lái)進(jìn)行信息隱藏的方式是另一個(gè)有效減少全局污染的方法。
*/
如對(duì)本文有疑問(wèn),請(qǐng)?zhí)峤坏浇涣髡搲?,廣大熱心網(wǎng)友會(huì)為你解答??! 點(diǎn)擊進(jìn)入論壇