1. 對象的簡單介紹與一些注意事項正則表達式
JavaScript中具備幾個簡單數據類型:數字、字符串、布爾值、null值以及undefined值。除此以外其他全部值(包括數組、函數,甚至正則表達式)都是對象。數字、字符串以及布爾值表面是對象(由於他們具備方法),但它們是不可變的,只是JavaScript在引用某個數字、字符串或者布爾值時,經過調用new Number()、new String()和new Boolean()構造器將其轉換爲了數字、字符串或布爾對象,它自有的方法也是從原型中繼承而獲得。基本數據類型不能夠被改變,所以在沒有指針再指向它時,它在內存中佔用的資源自動被釋放,而對象卻永遠以引用的方式傳遞,改變對象中的值,也就改變了它在內存中的值。數組
注:理論上說,null值就是null值,不該該被檢測爲對象,但實際上,因爲JavaScript的設計失誤,typeof null === "object"是一個事實。閉包
所以在檢驗null值時,儘可能要使用其餘方法如:!null === true。例如,要檢測一個剛獲取的DOM對象是否正常獲取到了,咱們應該使用以下的代碼:函數
1 var element = document.getElementById("elementID"); 2 if(element){} 3 // 或者if(!element){}
而不要使用:測試
1 var element = document.getElementById("elementID"); 2 if(typeof element !== "object") {} 3 // 或者if(typeof element === "object") {}
上面說到,由於typeof null === "object",這樣下面這段代碼中,即便element獲取不正常(即值爲null)時,if語句也會按照獲取正常的結果辦事。spa
2. 對象的屬性prototype
對象存在的意義就是它能夠有許多的屬性和方法幫助咱們表達邏輯。對象的屬性能夠爲任意的值,能夠是數字、字符串、布爾值、null值,也能夠是對象或者是函數(固然函數本質上也是對象)。輸出一個屬性,若是它已經被定義,可是一個null值,就會對應輸出null,若是它甚至還未被定義,就會對應輸出undefined。設計
咱們先用字面量定義一個對象,方便後面的測試:指針
1 var game = { 2 name: "Mini Warior", 3 id: 201907271234, 4 qualification: { 5 type: "test" 6 } 7 }
咱們對對象屬性的操做通常來講就是CURD,最經常使用的就是修改更新和檢索取值。code
修改更新一個對象的屬性,咱們能夠直接使用賦值語句。而通常檢索並獲取對象的屬性,有兩種方法:第一種,由於更緊湊可讀性更強而最爲經常使用的一種: var gameName = game.name; 咱們稱爲(這裏有個點↘). 表示法;第二種,就像獲取數組對應下標的值同樣: var gameName = game["name"]; 。檢索獲取屬性值時,咱們也要考慮到屬性不存在的狀況,這時候咱們能夠巧用運算符填充默認值: var gameName = game.name || "Mini Warior"; 。這時候若是game.name獲取爲null值或undefined值,gameName也會被賦值爲你所但願的初始值,而不會影響接下來代碼的運行。若是咱們嘗試從undefined的屬性中取值,例如 var gameQualiPlayer = game.qualification.player; ,JavaScript將會拋出一個「TypeError」的錯誤,咱們也能夠巧用&&運算符: var gameQualiPlayer = game.qualification && game.qualification.player; 避免錯誤,但結果仍然是取出一個undefined值。
處理一些不須要的屬性(例如原型鏈上的屬性)時,咱們除了使用typeof關鍵字之外,還有一種辦法是使用Object.prototype.hasOwnProperty()方法。這個方法會返回布爾值,值爲填入的參數是否在當前的對象中。比較經常使用的用法是在使用for in語句遍歷對象時,for in語句默認會遍歷到原型鏈上的屬性。假如在開發過程當中原型鏈上的屬性被其餘人修改,而你不清楚,就會發生莫名的錯誤。所以在使用for in語句時使用這個方法會更爲保險:
1 var player = { 2 name: 'Lyn', 3 age: 19, 4 gender: 'male' 5 }; 6 7 var playerPropertyName = []; 8 var playerProperty = []; 9 10 for(var key in player) { 11 playerPropertyName.push(i); 12 playerProperty.push(player[i]); 13 }
上面這段代碼把player中的屬性的鍵存入playerPropertyName數組,把player屬性的值存入playerProperty數組中。下面在player原型鏈上加入新的屬性,並使用Object.prototype.hasOwnProperty()過濾:
1 var player = { 2 name: 'Lyn', 3 age: 19, 4 gender: 'male' 5 }; 6 player.prototype.playGame = 'Mini Warior'; 7 8 var playerPropertyName = []; 9 var playerProperty = []; 10 11 for (var key in player){ 12 if(player.hasOwnProperty(key){ 13 playerPropertyName.push(i); 14 playerProperty.push(player[i])' 15 } 16 }
這樣,在遍歷過程當中,就不會把playGame的鍵和值存到對應數組裏面。
對象的屬性有的可枚舉,有的不可枚舉。像咱們上面這樣使用for in語句遍歷一個對象時,全部可枚舉的屬性或方法都會受到影響,所以咱們提到可使用typeof關鍵字或hasOwnProperty方法進行過濾。但咱們知道,JavaScript中Array也是對象,咱們創建數組,輸出它,會發現數組的下標是鍵,值是值,還有一個不可枚舉的length屬性(固然還有原型)。在這種狀況下,咱們使用for in語句就不會影響到length屬性。for in語句不只容易遍歷到方法和原型屬性,還沒法控制屬性名的順序,所以咱們遍歷的最佳實踐應該是使用普通的for語句而不是for in語句(固然,當講到閉包時,咱們也會發現for語句也並非完美的,但至少它在大多數狀況下都比for in遍歷要好)。
至於對象屬性的刪除,咱們會使用到delete運算符,須要注意的一點就是它將不會觸及到原型鏈裏的內容,但刪除此對象的屬性後,可能會讓原型鏈的屬性浮現:假設咱們有一個player對象,它有一個屬性nickname: "Lyn",它的原型上也有一個屬性nickname: "Ben",通過 delete player.nickname; 後,輸出player.nickname的值爲Ben。
對象幫助咱們編寫可擴展、可重用、高質量的JavaScript庫。但固然,對象還有幾個重要的概念是原型鏈和對象的建立,它值得咱們放到一篇新的博客中講述。