在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ HTML/ 對象與 JSON
面向?qū)ο蟮?Javascript
客戶端的 JavaScript
概述
核心概念深入
函數(shù)式的 Javascript
對象與 JSON
前端 JavaScript 框架
基本概念
數(shù)組
閉包
正則表達(dá)式
函數(shù)

對象與 JSON

JavaScript 對象與傳統(tǒng)的面向?qū)ο笾械膶ο髱缀鯖]有相似之處,傳統(tǒng)的面向?qū)ο笳Z言中,創(chuàng)建一個(gè)對象必須先有對象的模板:類,類中定義了對象的屬性和操作這些屬性的方法。通過實(shí)例化來構(gòu)筑一個(gè)對象,然后使用對象間的協(xié)作來完成一項(xiàng)功能,通過功能的集合來完成整個(gè)工程。而 Javascript 中是沒有類的概念的,借助 JavaScript 的動態(tài)性,我們完全可以創(chuàng)建一個(gè)空的對象(而不是類),通過像對象動態(tài)的添加屬性來完善對象的功能。

JSON 是 JavaScript 中對象的字面量,是對象的表示方法,通過使用 JSON,可以減少中間變量,使代碼的結(jié)構(gòu)更加清晰,也更加直觀。使用 JSON,可以動態(tài)的構(gòu)建對象,而不必通過類來進(jìn)行實(shí)例化,大大的提高了編碼的效 率。

對象

JavaScript 對象其實(shí)就是屬性的集合,這里的集合與數(shù)學(xué)上的集合是等價(jià)的,即具有確定性,無序性和互異性,也就是說,給定一個(gè) JavaScript 對象,我們可以明確的知道一個(gè)屬性是不是這個(gè)對象的屬性,對象中的屬性是無序的,并且是各不相同的(如果有同名的,則后聲明的覆蓋先聲明的)。

一般來說,我們聲明對象的時(shí)候?qū)ο笸皇且粋€(gè)空的集合,不包含任何的屬性,通過不斷的添加屬性,使得該對象成為一個(gè)有完整功能的對象,而不用通過創(chuàng)建一個(gè)類,然后實(shí)例化該類這種模式,這樣我們的代碼具有更高的靈活性,我們可以任意的增刪對象的屬性。

如果讀者有 Python 或其他類似的動態(tài)語言的經(jīng)驗(yàn),就可以更好的理解 JavaScript 的對象,JavaScript 對象的本身就是一個(gè)字典(dictionary),或者 Java 語言中的 Map,或者稱為關(guān)聯(lián)數(shù)組,即通過鍵來關(guān)聯(lián)一個(gè)對象,這個(gè)對象本身又可以是一個(gè)對象,根據(jù)此定義,我們可以知道 JavaScript 對象可以表示任意復(fù)雜的數(shù)據(jù)結(jié)構(gòu)。

對象的屬性

屬性是由鍵值對組成的,即屬性的名字和屬性的值。屬性的名字是一個(gè)字符串,而值可以為任意的 JavaScript 對象(JavaScript 中的一切皆對象,包括函數(shù))。比如,聲明一個(gè)對象:

var jack = new Object();  
jack.name = "jack";  
jack.age = 26;  
jack.birthday = new Date(1984, 4, 5);  

//聲明另一個(gè)對象  
var address = new Object();  
address.street = "Huang Quan Road";  
address.xno = "135";  

//將addr屬性賦值為對象address  
jack.addr = address;  

這種聲明對象的方式與傳統(tǒng)的 OO 語言是截然不同的,它給了我們極大的靈活性來定制一個(gè)對象的行為。

對象屬性的讀取方式是通過點(diǎn)操作符(.)來進(jìn)行的,比如上例中 jack 對象的 addr 屬性,可以通過下列方式取得:

var ja = jack.addr;  

ja = jack[addr];  

后者是為了避免這種情況,設(shè)想對象有一個(gè)屬性本身包含一個(gè)點(diǎn)(.),這在 JavaScript 中是合法的,比如說名字為 foo.bar,當(dāng)使用 jack.foo.bar 的時(shí)候,解釋器會誤以為 foo 屬性下有一個(gè) bar 的字段,因此可以使用 jack[foo.bar]來進(jìn)行訪問。通常來說,我們在開發(fā)通用的工具包時(shí),應(yīng)該對用戶可能的輸入不做任何假設(shè),通過[屬性名]這種形式則總是可以保證正確性的。

屬性與變量

在第二章,我們講解了變量的概念,在本章中,讀者可能已經(jīng)注意到,這二者的行為非常相似,事實(shí)上,對象的屬性和我們之前所說的變量其實(shí)是一回事。

JavaScript 引擎在初始化時(shí),會構(gòu)建一個(gè)全局對象,在客戶端環(huán)境中,這個(gè)全局對象即為window。如果在其他的JavaScript 環(huán)境中需要引用這個(gè)全局對象,只需要在頂級作用域(即所有函數(shù)聲明之外的作用域)中聲明:

var global = this; 

我們在頂級作用域中聲明的變量將作為全局對象的屬性被保存,從這一點(diǎn)上來看,變量其實(shí)就是屬性。比如,在客戶端,經(jīng)常會出現(xiàn)這樣的代碼:

var v = "global";  

var array = ["hello", "world"];  

function func(id){  
    var element = document.getElementById(id);  
    //對elemen做一些操作  
} 

事實(shí)上相當(dāng)于:

window.v = "global";  

window.array = ["hello", "world"];  

window.func = function(id){  
    var element = document.getElementById(id);  
    //對elemen做一些操作    
}  

原型對象

原型(prototype),是 JavaScript 特有的一個(gè)概念,通過使用原型,JavaScript 可以建立其傳統(tǒng) OO 語言中的繼承,從而體現(xiàn)對象的層次關(guān)系。JavaScript 本身是基于原型的,每個(gè)對象都有一個(gè) prototype 的屬性來,這個(gè) prototype 本身也是一個(gè)對象,因此它本身也可以有自己的原型,這樣就構(gòu)成了一個(gè)鏈結(jié)構(gòu)。 訪問一個(gè)屬性的時(shí)候,解析器需要從下向上的遍歷這個(gè)鏈結(jié)構(gòu),直到遇到該屬性,則返回屬性對應(yīng)的值,或者遇到原型為 null 的對象(JavaScript 的基對象 Object 的 prototype 屬性即為 null),如果此對象仍沒有該屬性,則返回 undefined. 下面我們看一個(gè)具體的例子:

//聲明一個(gè)對象base  
function Base(name){  
    this.name = name;  
    this.getName = function(){  
       return this.name;  
    }  
}  

//聲明一個(gè)對象child  
function Child(id){  
    this.id = id;  
    this.getId = function(){  
       return this.id;    
    }  
}  

//將child的原型指向一個(gè)新的base對象  
Child.prototype = new Base("base");  

//實(shí)例化一個(gè)child對象  
var c1 = new Child("child");  

//c1本身具有g(shù)etId方法  
print(c1.getId());  
//由于c1從原型鏈上"繼承"到了getName方法,因此可以訪問  
print(c1.getName());  

得出結(jié)果:

child
base

由于遍歷原型鏈的時(shí)候,是有下而上的,所以最先遇到的屬性值最先返回,通過這種機(jī)制可以完成重載的機(jī)制。

this 指針

JavaScript 中最容易使人迷惑的恐怕就數(shù) this 指針了,this 指針在傳統(tǒng) OO 語言中,是在類中聲明的,表示對象本身,而在 JavaScript 中,this 表示當(dāng)前上下文,即調(diào)用者的引用。這里我們可以來看一個(gè)常見的例子:

//定義一個(gè)人,名字為jack  
var jack = {  
    name : "jack",  
    age : 26  
}  

//定義另一個(gè)人,名字為abruzzi  
var abruzzi = {  
    name : "abruzzi",  
    age : 26  
}  

//定義一個(gè)全局的函數(shù)對象  
function printName(){  
    return this.name;  
}  

//設(shè)置printName的上下文為jack, 此時(shí)的this為jack  
print(printName.call(jack));  
//設(shè)置printName的上下文為abruzzi,此時(shí)的this為abruzzi  
print(printName.call(abruzzi));  

運(yùn)行結(jié)果:

jack
Abruzzi

應(yīng)該注意的是,this 的值并非函數(shù)如何被聲明而確定,而是被函數(shù)如何被調(diào)用而確定,這一點(diǎn)與傳統(tǒng)的面向?qū)ο笳Z言截然不同,call 是 Function 上的一個(gè)函數(shù),詳細(xì)描述在第四章。

使用對象

對象是 JavaScript 的基礎(chǔ),我們使用 JavaScript 來完成編程工作就是通過使用對象來體現(xiàn)的,這一小節(jié)通過一些例子來學(xué)習(xí)如何使用 JavaScript 對象:

對象的聲明有三種方式:

  • 通過 new 操作符作用域 Object 對象,構(gòu)造一個(gè)新的對象,然后動態(tài)的添加屬性,從無到有的構(gòu)筑一個(gè)對象。
  • 定義對象的“類”:原型,然后使用 new 操作符來批量的構(gòu)筑新的對象。
  • 使用 JSON,這個(gè)在下一節(jié)來進(jìn)行詳細(xì)說明

這一節(jié)我們詳細(xì)說明第二種方式,如:

//定義一個(gè)"類",Address  
function Address(street, xno){  
    this.street = street || 'Huang Quan Road';  
    this.xno = xno || 135;  
    this.toString = function(){  
       return "street : " + this.street + ", No : " + this.xno;     
    }  
}  

//定義另一個(gè)"類",Person  
function Person (name, age, addr) {  
  this.name = name || 'unknown';  
  this.age = age;  
  this.addr = addr || new Address(null, null);  
  this.getName = function () {return this.name;}  
  this.getAge = function(){return this.age;}  
  this.getAddr = function(){return this.addr.toString();}  
}  

//通過new操作符來創(chuàng)建兩個(gè)對象,注意,這兩個(gè)對象是相互獨(dú)立的實(shí)體  
var jack = new Person('jack', 26, new Address('Qing Hai Road', 123));  
var abruzzi = new Person('abruzzi', 26);  

//查看結(jié)果  
print(jack.getName());  
print(jack.getAge());  
print(jack.getAddr());  

print(abruzzi.getName());  
print(abruzzi.getAge());  
print(abruzzi.getAddr());  

運(yùn)行結(jié)果如下:

jack
26
street : Qing Hai Road, No : 123
abruzzi
26
street : Huang Quan Road, No : 135

JSON 及其使用

JSON 全稱為 JavaScript 對象表示法(JavaScript Object Notation),即通過字面量來表示一個(gè)對象,從簡單到復(fù)雜均可使用此方式。比如:

var obj = {  
    name : "abruzzi",  
    age : 26,  
    birthday : new Date(1984, 4, 5),  
    addr : {  
       street : "Huang Quan Road",  
       xno : "135"  
    }  
} 

這種方式,顯然比上邊的例子簡潔多了,沒有冗余的中間變量,很清晰的表達(dá)了 obj 這樣一個(gè)對象的結(jié)構(gòu)。事實(shí)上,大多數(shù)有經(jīng)驗(yàn)的 JavaScript 程序員更傾向與使用這種表示法,包括很多 JavaScript 的工具包如 jQuery,ExtJS 等都大量的使用了 JSON。JSON 事實(shí)上已經(jīng)作為一種前端與服務(wù)器端的數(shù)據(jù)交換格式,前端程序通過 Ajax 發(fā)送 JSON 對象到后端,服務(wù)器端腳本對 JSON 進(jìn)行解析,還原成服務(wù)器端對象,然后做一些處理,反饋給前端的仍然是 JSON 對象,使用同一的數(shù)據(jù)格式,可以降低出錯(cuò)的概率。

而且,JSON 格式的數(shù)據(jù)本身是可以遞歸的,也就是說,可以表達(dá)任意復(fù)雜的數(shù)據(jù)形式。JSON 的寫法很簡單,即用花括號括起來的鍵值對,鍵值對通過冒號隔開,而值可以是任意的 JavaScript 對象,如簡單對象 String,Boolean,Number,Null,或者復(fù)雜對象如 Date,Object,其他自定義的對象等。

JSON 的另一個(gè)應(yīng)用場景是:當(dāng)一個(gè)函數(shù)擁有多個(gè)返回值時(shí),在傳統(tǒng)的面向?qū)ο笳Z言中,我們需要組織一個(gè)對象,然后返回,而 JavaScript 則完全不需要這么麻煩,比如:

function point(left, top){  
    this.left = left;  
    this.top = top;  
    //handle the left and top  
    return {x: this.left, y:this.top};  
}  

直接動態(tài)的構(gòu)建一個(gè)新的匿名對象返回即可:

var pos = point(3, 4);  
//pos.x = 3;  
//pos.y = 4; 

使用 JSON 返回對象,這個(gè)對象可以有任意復(fù)雜的結(jié)構(gòu),甚至可以包括函數(shù)對象。 在實(shí)際的編程中,我們通常需要遍歷一個(gè) JavaScript 對象,事先我們對對象的內(nèi)容一無所知。怎么做呢?JavaScript 提供了 for..in 形式的語法糖:

for(var item in json){  
    //item為鍵  
    //json[item]為值  
} 

這種模式十分有用,比如,在實(shí)際的WEB應(yīng)用中,對一個(gè)頁面元素需要設(shè)置一些屬性,這些屬性是事先不知道的,比如:

var style = {  
    border:"1px solid #ccc",  
    color:"blue"  
};  

然后,我們給一個(gè) DOM 元素動態(tài)的添加這些屬性:

for(var item in style){  
    //使用jQuery的選擇器  
    $("div#element").css(item, style[item]);  
}

當(dāng)然,jQuery 有更好的辦法來做這樣一件事,這里只是舉例子,應(yīng)該注意的是,我們在給$("div#element")添加屬性的時(shí)候,我們對 style 的結(jié)構(gòu)是不清楚的。

另外比如我們需要收集一些用戶的自定義設(shè)置,也可以通過公開一個(gè) JSON 對象,用戶將需要設(shè)置的內(nèi)容填入這個(gè) JSON,然后我們的程序?qū)ζ溥M(jìn)行處理。

function customize(options){  
    this.settings = $.extend(default, options);  
}
上一篇:函數(shù)下一篇:數(shù)組