js對象小結

前奏

      對象是js的基本數據類型,準確來講除了字符串,數字,boolean值,null與undifine以外,js中的值都是對象。js中的對象是一種複合值,他將不少值(原始值或其餘對象)聚合在一塊兒,能夠經過名字來訪問這些值,其實看上去就像是一個屬性的無序集合,每一個屬性都是一個名/值對。屬性名是字符串,能夠把對象當作是從字符串到值得映射。這種現象就像咱們平時知道的「關聯數組」,「數據字典」等等(只是叫法不一樣而已)。除了這種映射關係外,最主要的核心就是js的對象能夠經過「原型繼承」來繼承屬性與方法。另外因爲對象時可變的,咱們是經過引用而非值來操做對象。html

首先咱們先來講一下對象的屬性,對象的屬性包括屬性名與屬性值。其中屬性名是一個包含空字符在內的任意字符串(關於屬性名加不加雙引號的問題,規範是要加的,可是在沒有特殊字符,或是按照的json的數據格式來就須要加了,這樣避免特殊字符或是數據傳輸出錯)。屬性值可使js的任意值。除了名字之外每一個屬性還有一些和他相關的性質,被叫作「屬性特性」:
可寫:是否能夠設置該屬性的值
可枚舉:代表是否可使用for/in循環遍歷屬性的值。
可配置:是否能夠刪除或修改該屬性。
其次除了包含屬性以外,每一個對象還包含三個相關的對象特質:
一、對象的原型(prototype)指向另一個對象,本對象的屬性繼承自這個原型對象。
二、對象的類(class)是一個標示對象類型的字符串
三、對象的擴展標記(extensible flag)指明瞭(在ECMAScript 5中)是否能夠向該對象添加新的屬性
最後咱們使用下面的術語來對咱們經常使用的三類js對象與兩類屬性作區分:
一、內置對象(native object)使用ECMAScript 規範的對象或類,例如數組,函數,日期和正則表達式都是內置對象
二、宿主對象(host object)是由js解釋器所嵌入的宿主環境定義的。客戶端js中標示網頁結構的HTMLElement對象均是宿主對象,在這種環境下宿主對象至關因而內置對象
三、自定義對象(user defined object)是又運行中的js代碼建立的對象
四、自由屬性(own property)是直接在對象中定義的屬性
五、繼承屬性(inherited property)是在對象的原型上定義的屬性
 
對象的建立
     說了這麼多咱們尚未聊到怎麼建立最簡單的對象。接下來就是怎麼建立對象了。
建立對象的方式有三中:經過對象直接量(對象字面量),經過關鍵字new和(ECMAScript 5中)經過Object.create()來建立對象。
一、建立對象最簡單的方式就是在js中使用對象直接量。
對象直接量是由若干的名/值對組成的映射表,名/值之間使用冒號分隔,名/值對之間使用逗號分隔,整個映射表用花括號擴起來。關於屬性名前面已經提及。
var empty = {};   //  定義一個空對象
var ob1 = {x:1,y:2};   //  定義兩個屬性的對象
var ob2 = {           // 定義複雜的對象
          "main title" : "three object",    
          "main-t" : 123,               //   特殊字符要加引號
          "for" : {x:"123",y:123},   //  for是保留字必須用引號
 };
對象直接量是一個表達式,這個表達式的每次運算都會建立並初始化一個新的對象。若是在循環表達式裏使用對象直接量,他將會建立不少對象的。
二、經過new來建立對象.
用new關鍵字來建立一個對象,new後跟一個函數調用,這裏的函數稱爲構造函數(constructor),構造函數用以初始化一個新建立的對象,js語言核心中的原始類型都包含內置的構造函數。除了這些內置的構造函數外,咱們最經常使用的就是咱們自定義的構造函數了。例如:
var arr = new Array();      //   使用內置構造函數建立一個新的數組對象,至關於var arr = [];
var obg = new Object();      //  使用內置構造函數建立一個新的數組對象,至關於var arr = {};
function UserDefineObj (x,y) {        //  自定義的構造函數
                   this.x = x;
                    this.y = y;
               }   
var user = new UserDefineObj(1,2);    //  使用自定義的構造函數建立一個對象
三、使用Object.create()方法
ECMAScript  5定義了一個名爲Object.create()方法來建立一個新對象,這個方法的第一個參數是這個對象的原型,Object.create()提供的第二個可選參數是用來對對象的屬性做進一步的描述。
Object.create()是一個靜態函數,而不是提供給某一個對象的方法,使用他的方法很簡單隻須要傳入一個原型對象便可:例如
var ob1 = Object.create ( {x : 1, y : 2 } );     //  使用後面的參數(對象直接量)做爲ob1對象的原型。

若是想建立一個空對象(好比經過{ }或newObject()建立的對象)可使用Object.prototype做爲這個方法的參數。例如:正則表達式

var ob2 = Object.create ( { } ) ;     //  建立一個空對象

若是傳入參數爲null,將會建立一個沒有任何原型的空對象,但這個對象沒有任何繼承的方法,甚至不包括基礎的方法,如toString()等。json

var ob3 = Object.create (null);      //  ob3不繼承任何屬性和方法
 
對象的繼承
說到js的繼承咱們不得不提的就是js的核心特色:基於原型(prototype)繼承。
 
原型:
       首先來看一下原型。每個js對象(除了null)都有一個對象與其相關聯,這個相關聯的對象就是咱們所說的原型對象。每個對象都從原型繼承屬性。
全部經過對象直接量建立的對象都具備同一個原型,並經過js代碼Object.prototype得到對原型對象的引用。也就是說經過直接量建立的對象的原型就是Object.prototype引用的一個對象。
經過new關鍵字與構造函數建立的對象的原型就是構造函數的prototype的屬性的值。所以,不管是用對象直接量建立的對象,仍是經過new Object()建立的對象同時都繼承自Object.prototype。同時new Array()建立的對象的原型就是Array.Prototype,使用new Date()建立的對象的原型就是Date.prototype.
沒有原型的對象爲數很少,其中Object.prototype就是其中一個,他不繼承任何屬性。其餘的對象的原型對象都是普通的對象。另外全部的內置函數以及大部分自定義的函數(上面說過一個ob3對象沒有原型)都有一個繼承自Object.prototype的原型。所以new Date()既繼承自Date.prototy同時也繼承自Object.prototype。這一系列相互關聯的原型對象也就構成了所謂的原型鏈(prototyp chain)。
例如:
function UserDefineObj (x,y) {        //  自定義的構造函數
                   this.x = x;
                    this.y = y;
               }
var user = new UserDefineObj(1,2);    //  使用自定義的構造函數建立一個對象
console.log(user.toString());           //   toString這個方法就是繼承自Object.prototype

關於原型與原型鏈推薦博客:http://www.cnblogs.com/TomXu/archive/2012/01/05/2305453.html數組

繼承:
js對象具備自定義的屬性,也有一些事繼承自原型對象的屬性。下面咱們將用實例來討論js的繼承關係。
function UserDefineObj (x,y) {        //  自定義的構造函數
                   this.x = x;               //   聲明自定義屬性x,也成爲自有屬性
                    this.y = y;               //   聲明自定義屬性y
               }
UserDefineObj.prototype.allx = 123;      //   給構造函數的原型對象添加屬性allx 
var user = new UserDefineObj(1,2);    //  使用自定義的構造函數建立一個對象
console.log(user.x);              //  輸出:1
console.log(user.allx);           //   輸出:123

因爲js是一種弱類型的語言,在不聲明變量的狀況下,解析器會自動的再運行的時候建立這個變量(全局變量)。函數

  function UserDefineObj (x,y) {        //  自定義的構造函數
                   this.x = x;               //   聲明自定義屬性x,也成爲自有屬性
                    this.y = y;               //   聲明自定義屬性y
               }
               UserDefineObj.prototype.allx = 123;      //   給構造函數的原型對象添加屬性allx
               var user = new UserDefineObj(1,2);    //  使用自定義的構造函數建立一個對象
               var ob = new UserDefineObj(4,5);
               console.log(user.x);              //  輸出:1
               console.log(ob.x);       //  輸出:4
               console.log(user.allx);    //  輸出:123
               console.log(ob.allx);      //   輸出:123
               user.allx = 110;            //  更改user對象的屬性,對ob對象沒有影響
               console.log(user.allx);      //   輸出:110
               console.log(ob.allx);        //   輸出:123

從上面程序的輸出能夠看出user對象和ob對象建立了兩個不一樣的對象,這兩個對象同時共同繼承自原型對象UserDefineObj.prototype。因爲是不一樣的對象,因此對屬性的值得改變,對其餘的對象沒有影響。this

相關文章
相關標籤/搜索