我真的很佩服副院長~他是一個很有耐心 極其細致的人
工作態度嚴謹 代碼簡潔風格統一~再亂遭遭的代碼只要經過他的手就會變的很漂亮
羡煞我也~
不說廢話了 還是乖乖看書吧~maybe可能也許的某一天 我也可以。。。咕~~(╯﹏╰)b還是別做白日夢了
--------------part2--------------------------------------------------------------------------------------------------------
注釋:ECMA5-ECMAScript5
在開始之前,先講一下關於變量的知識:
好的習慣1:把所有的變量聲明放置在函數的開頭是一個好的編程習慣
還有一個很重要的概念~不可變的原始值和可變的對象引用(基本類型和引用類型)
javascript中的原始值:undefined null boolean string number 原始值是不可修改的。只有他們的值相等時他們才會相等。
引用類型:對象(包括數組和函數) 他們的值是可以修改的。對象的比較均是引用的比較,當且僅當他們引用同一個基對象時,他們才相等。
這就是為什么在工作中碰到一個問題~就是我明明沒有對一個數組進行操作,為什么最后它的值卻改變了
記住這一句話:變量保存了基本類型的實際值,而對於引用類型只保存對它的引用值。

eg:基本類型(數值 布爾值,null和undefined) var a=1; var b=a; var a = 3.14; alert(b) b = 1 引用類型(對象,數組和函數) var a =[1,2,3] var b =a; a[0] = 99; alert(b) b = [99,2,3]
先了解下typeof運算符:
x typeof x undefined "undefined" null "object" true/false "boolean" 任意數字或NaN "number" 任意字符串 "string" 任意函數 "function" 任意內置對象(非函數) "object"
對象:
除了字符串、數字、true、false、null和undefined之外,javascript中的值都是對象,盡管,最常見的用法是創建,設置,查找, 刪除,檢測和枚舉。
1:對象的創建
可以通過對象直接量,關鍵字new和ECMA5中的object.creat()創建對象。
我想前面2個大家都很熟悉,對於第3個的方式首先解釋下原型。這也是我很薄弱但是確又是很重要的知識點(\(^o^)/~我要開始啰嗦了哈)。
每個Javascript對象(null除外)都和一個對象相關聯。“另一個”對象就是我們熟知的原型,每一個對象都從原型繼承屬性。
現在我們來分析下~
對象直接量創建對象都具有同一個原型-object.prototype
通過關鍵字new和構造函數調用創建的對象的原型就是構造函數的prototype屬性的值。
沒有原型的對象為數不多,object.prototype就是其中之一。他不繼承任何屬性。其他的對象的原型都是普通對象,普通對象都具有原型。所有的內置構造函數(以及大部分自定義的構造函數)都具有一個繼承自object.prototype的原型。
eg,Date.prototype的屬性繼承自object.prototype。這一系列鏈接的原型對象就是所謂的“原型鏈”
object.creat({x:1;y:2})它創建了一個對象,第一個參數是這個對象的原型。
object.creat({object.prototype}); //他和{}和new object()一樣
object.creat()他實現了“可以使任意對象可繼承”,這是一個強大的特性。此方法是ECMA5才有,那ECMA3如何去實現呢?
eg:通過原型繼承創建一個新的對象 function inherit(p){ if(p == null) throw TypeError(); if(object.create) return object.creat(p); var t = typeof p; if(p!=="object" && p!== "function")
throw TypeError()
function f(){}
f.prototype = p;
return new f(); //返回一個新的對象 它是原型是p
}
inherit()函數的其中一個用途就是防止庫函數無意間(非惡意的)修改那些不受你控制的對象
var o={x:"donit change this value"};
library_function(inherit(0));
2:對象的查詢及設置
對像的查詢還有設置可以用a.name 或者a[name].
注意只有在查詢屬性時才會體會到繼承的存在,而設置屬性則和繼承無關。
屬性訪問錯誤:當查詢對象一個不存在的屬性時不會報錯,o.x返回undefined;但是查詢不存在對象的屬性時就會報錯,o.x.length(null,undefined沒有屬性)
可以用更簡練的方法 var len = book&&book.x&&book.x.length;
3:刪除屬性
delete運算符可以只能刪除對象可枚舉的自有屬性。
注意delete只是斷開屬性和宿主對象的聯系,而不會去操作屬性中的屬性。
eg:a={b:{c:1}};var t = a.b;delete a.b;consolse.log({"x":t.c}) //{x:1}
由於已經刪除的屬性的引用依然存在,所以t.c的值還是1,所以在銷毀對象的時候,要遍歷屬性中的屬性,依次刪除。否則會造成內存泄漏。
4:檢測屬性
in:"x" in o; 檢測自有屬性和繼承屬性
hasOwnProperty:o.hasOwnProperty("x") 檢測自有屬性
propertyIsEnumberable():o.propertyIsEnumberable("x") 他是hasOwnProperty的增強版,檢測可枚舉的自有屬性時返回true。
某些內置屬性是不可枚舉的,通常由javascript代碼創建的屬性都是可枚舉的,除非在ECMA5中使用一個特殊的方法來改變屬性的可枚舉性。
還有一種更簡單的 o.x!==undefined;if(o.x) o.x *=2;
5:枚舉屬性
for/in:遍歷對象中可枚舉的自有屬性和繼承屬性。對象繼承的內置對象是不可枚舉的。
要獲取一個對象的自有屬性經常這個樣子
for(prop in p){
if(p.hasOwnProperty(prop)){
.....
}
}
6:屬性setter和getter
對象屬性是由名字,值和一組特性(attribute)構成的。在ECMA5中,屬性值可以用一個或兩個方法替代,就是getter和setter。
由getter和setter定義的屬性稱做“存取器屬性”,它不同於”數據屬性“,數據屬性只有一個簡單的值。
當程序查詢存取器屬性時,調用getter方法。設置一個存取器屬性的值時,調用setter方法。
和數據屬性不同,存取器屬性不具有可寫性。如果屬性同時具有getter和setter,那么他是一個讀/寫屬性。如果他只有getter方法,那么它是一個只讀屬性。如果它只有setter方法,那么它是一個只寫屬性,讀取只寫屬性總是返回Unedfined.
和數據屬性相同的是存取器屬性時可以繼承的。
eg:var o = {
x:value,
get access(){/*函數體*/},
set access(){/*函數體*/}
};
7:屬性的特性
所有通過ECMA3的程序創建的屬性都是可寫的,可枚舉的和可配置的,且無法對這些特性做修改的。
但是ECMA5是可以查詢和設置這些屬性特性的API,這些API對於庫的開發者來說是非常重要的:
* 可以通過這些API給原型對象添加方法,並將它們設置成不可枚舉的,這讓它們看起來更像內置方法
* 可以通過這些API給對象定義不能修改或刪除的屬性,借此"鎖定"這個對象。
屬性包含一個名字和4個特性。數據屬性的4個特性是值(value)、可寫性(writable)、可枚舉性(enumberable)和可配置性(configurable)。
存取器屬性的4個特性是讀取(get)、寫入(set)、可枚舉性和可配置性。
為了實現屬性特性的查詢和設置操作,ECMA5定義了一個“屬性描述符”的對象
object.getOwnPropertyDescriptor({x:1},x):獲取某個對象特定屬性的屬性描述符,稚嫩而過得到自有屬性的描述符。要想獲得繼承屬性的特性,需要遍歷原型鏈(object.getPrototypeOf())
var o ={};
object.defineProperty(o,"x",{value:1,writable:true,enumerable:false,configurable:true});o.x;//1 object.keys(o);//[]
這個方法要么修改已有屬性要么新建自有屬性,但不能修改繼承屬性。
object.defineProperties():同時修改或創建多個屬性
這個我就不在深入討論了~細節問題請看Page136
7:對象的三個屬性
每個對象都有與之相關聯的原型(prototype),類(class)和可擴展性(extensible)。這些屬性有什么作用呢,以及如何去查詢和設置他們呢?
原型屬性:在實例對象創建之初就是設置好的~這個我就不繼續多說了。
在ECMA5中,Object.getPrototypeOf()可以查詢他的原型鏈,ECMA3中滅有等價的函數,可以用o.constructor.prototype來檢測一個對象的原型,這種方式並不可靠,請參考后面的內容“類和模塊”的講解。
isPrototype():檢測一個對象是否是另一個對象的原型(或處於原型鏈中)
instanceof :判斷一個對象是否是一個類的實例。
var d= new Date();
d.instanceof Date; //true
d.instanceof Object; //true
類屬性:對象的類屬性是一個字符串,用以表示對象的類型信息。Page140
可擴展性:對象的可擴展性用以表示是否可以給對像添加新屬性。對象的可擴展性通常和屬性的可配置行與可寫性配合使用
8:序列化對象
對象序列化是指將對象的狀態轉化為字符串,也可將字符串轉化成對象。只能序列化對象可枚舉的自有屬性。對於一個不能序列化的屬性倆說,在序列化的輸出字符串中會將這個屬性省略掉。
ECMA5中提供了JSON.stringify()和JSON.parse()用來序列化和還原
ECMA3中可以通過引入json2.js模塊來使用ECMAScript5中的這些函數
9:toString()方法
默認的toString方法的返回值帶有的信息量很少,因此很多類都帶有自定義的toString().eg:Array.toString(),Date.toString()以及Function.toString();
10:valueOf()
跟toString方法類似,轉化為數字的時候用這個方法,返回值帶有的信息量很少,因此很多類都帶有自定義的valueOf().