第十章 變量、作用域及內(nèi)存
JavaScript的變量與其他語言的變量有很大區(qū)別。JavaScript變量是松散型的(不強(qiáng)制類型),決定了它只是在特定時(shí)間用于保存特定值的一個(gè)名字而已订咸。由于不存在定義某個(gè)變量必須要保存何種數(shù)據(jù)類型值的規(guī)則,變量的值及其數(shù)據(jù)類型可以在腳本的生命周期內(nèi)改變酬诀。
10.1 變量及作用域
(1) 值類型和引用類型
JavaScript的變量包括兩種類型脏嚷,即值類型和引用類型。
值類型:值類型指的是那些保存在棧內(nèi)存中的簡(jiǎn)單數(shù)據(jù)段瞒御,即這種值完全保存在內(nèi)存中的一個(gè)位置父叙。
引用類型:引用類型值則是指那些保存在堆內(nèi)存中的對(duì)象,意思是變量中保存的實(shí)際上只是一個(gè)指針,這個(gè)指針指向內(nèi)存中的另一個(gè)位置趾唱,該位置保存對(duì)象涌乳。
將一個(gè)值賦給變量時(shí),解析器必須確定這個(gè)值是值類型甜癞,還是引用類型值夕晓。值類型有以下幾種:Undefined、Null带欢、Boolean运授、Number和String。這些類型在內(nèi)存中分別占有固定大小的空間乔煞,他們的值保存在椨蹼空間,我們是通過按值訪問的渡贾。(在某些語言中逗宜,字符串以對(duì)象的形式來表示,因此被認(rèn)為是引用類型空骚。JavaScript放棄這一傳統(tǒng)纺讲。)
如果賦值的是引用類型的值,則必須在堆內(nèi)存中為這個(gè)值分配空間囤屹。由于這種值的大小不固定熬甚,因此不能把它們保存到棧內(nèi)存中。但內(nèi)存地址大小是固定的肋坚,因此可以將內(nèi)存地址保存在棧內(nèi)存中乡括。這樣,當(dāng)查詢引用類型的變量時(shí)智厌,先從棧中讀取內(nèi)存地址诲泌,然后再通過地址找到堆中的值。對(duì)于這種铣鹏,我們把它叫做按引用訪問敷扫。
(2) 動(dòng)態(tài)屬性
定義基本類型值和引用類型值的方式是相似的:創(chuàng)建一個(gè)變量并為該變量賦值。但是诚卸,當(dāng)這個(gè)值保存到變量中以后葵第,對(duì)不同類型值可以執(zhí)行的操作則大相徑庭。
<script>
//定義一個(gè)對(duì)象合溺,即引用類型
var car = new Object();
car.brand = "Mercedes Benz";
alert(car.brand);
//定義一個(gè)字符串變量羹幸,即值類型
var cellPhone = "iphone6";
cellPhone.color = "Gold";
alert(cellPhone.color);
</script>
(3) 變量復(fù)制
在變量復(fù)制方面,值類型和引用類型也有所不同辫愉。值類型復(fù)制的是值本身,而引用類型復(fù)制的是地址将硝。
//值類型復(fù)制
var car1 = "Mercedes Benz"; //在棧內(nèi)存生成一個(gè)car1的變量恭朗,保存的值為 'Mercedes Benz'
var car2 = car1; //在棧內(nèi)存再生成一個(gè)car2的變量屏镊,保存的值也是 'Mercedes Benz'
car2是雖然是car1的一個(gè)副本,但從圖示可以看出痰腮,它是完全獨(dú)立的而芥。也就是說,兩個(gè)變量分別操作時(shí)互不影響膀值。
//引用類型復(fù)制
var car1 = new Object();
car.brand = "Mercedes Benz";
var car2 = car1;
car2.brand = "BMW";
alert(car1.brand);
引用類型中棍丐,car2其實(shí)就是car1,因?yàn)樗麄冎赶虻氖峭粋€(gè)對(duì)象沧踏。如果這個(gè)對(duì)象中的name屬性被修改了歌逢,car2.name和car1.name輸出的值都會(huì)被相應(yīng)修改掉了。
(4) 傳遞參數(shù)
JavaScript中所有函數(shù)的參數(shù)都是按值傳遞的翘狱,言下之意就是說秘案,參數(shù)不會(huì)按引用傳遞,雖然變量有基本類型和引用類型之分潦匈。
<script>
function sum(num){ //按值傳遞阱高,傳遞的參數(shù)是基本類型
num += 10; //這里的num是局部變量
return num;
}
var num = 10;
var result = sum(num);
alert(result);
alert(num);
</script>
以上的代碼中,傳遞的參數(shù)是一個(gè)值類型茬缩。而函數(shù)里的num是一個(gè)局部變量赤惊,和外面的num沒有任何聯(lián)系癞尚。
<script>
function setName(obj){ //按值傳遞旋恼,傳遞的參數(shù)是引用類型
obj.name = "馬云";
var obj = new Object();
obj.name = "劉強(qiáng)東";
}
var obj = new Object();
setName(obj);
alert(obj.name); //馬云
</script>
(5) 檢測(cè)類型
要檢測(cè)一個(gè)變量的類型,我們可以通過typeof運(yùn)算符來判別蛋欣。諸如:
<script>
var name = "Johnny";
alert(typeof name);
</script>
雖然typeof運(yùn)算符在檢查值類型的數(shù)據(jù)的時(shí)候非常好用寡夹,但檢測(cè)引用類型的時(shí)候处面,它就不是那么好用了。通常菩掏,我們并不想知道它是不是對(duì)象魂角,而是想知道它到底是什么類型的對(duì)象。因?yàn)閿?shù)組也是object智绸,null也是Object等等野揪。對(duì)于引用類型的檢測(cè),當(dāng)需要知道這個(gè)引用類型具體是什么對(duì)象的時(shí)候瞧栗,應(yīng)該使用instanceof運(yùn)算符斯稳。
<script>
var obj1 = [1,2,3];
alert(obj1 instanceof Array); //是否是數(shù)組
var obj2 = {};
alert(obj2 instanceof Object); //是否是對(duì)象
var obj3 = new String('Lee');
alert(obj3 instanceof String); //是否是字符串對(duì)象
</script>
注意:當(dāng)使用instanceof檢查基本類型的值時(shí),它會(huì)返回false迹恐。
(6) 執(zhí)行環(huán)境及作用域
執(zhí)行環(huán)境是JavaScript中最為重要的一個(gè)概念挣惰。執(zhí)行環(huán)境定義了變量或函數(shù)有權(quán)訪問的其他數(shù)據(jù),決定了它們各自的行為。
(1) 全局執(zhí)行環(huán)境(全局作用域)
全局執(zhí)行環(huán)境是最外圍的執(zhí)行環(huán)境憎茂。在Web瀏覽器中珍语,全局執(zhí)行環(huán)境被認(rèn)為是window對(duì)象。因此所有的全局變量和函數(shù)都是作為window對(duì)象的屬性和方法創(chuàng)建的竖幔。全局的變量和函數(shù)板乙,都是window對(duì)象的屬性和方法。
var color = "blue";
function showColor(){
alert(color);
}
showColor();
var color = "blue";
function showColor(){
alert(window.color);
}
window.showColor();
當(dāng)執(zhí)行環(huán)境中的所有代碼執(zhí)行完畢后拳氢,該環(huán)境被銷毀募逞,保存在其中的所有變量和函數(shù)定義也隨之銷毀。如果是全局環(huán)境下馋评,需要程序執(zhí)行完畢放接,或者網(wǎng)頁(yè)被關(guān)閉才會(huì)銷毀。
(2) 局部執(zhí)行環(huán)境(局部作用域)
函數(shù)里的局部作用域里的變量替換全局變量栗恩,但作用域僅限在函數(shù)體內(nèi)這個(gè)局部環(huán)境透乾。
<script>
var color = "blue"; //全局變量
function setColor(color){
color = color; //局部變量
alert(color);
}
setColor("red");
alert(color);
</script>
(7) 沒有塊及作用域
塊級(jí)作用域表示諸如if語句等有花括號(hào)封閉的代碼塊,所以磕秤,支持條件判斷來定義變量乳乌。
<script>
if (true) { //if語句代碼塊沒有局部作用域
var color = 'red';
}
alert(color);
for (var i = 0; i < 10; i ++){ //沒有局部作用域
var fullName = 'Johnny';
}
alert(i);
alert(fullName);
</script>
<script>
var color = "red";
function sum(num1, num2){
var num = num1 + num2;
return num;
}
sum(1, 2);
alert(num); //報(bào)錯(cuò) num is not defined
</script>
注意:定義及初始化變量的時(shí)候一定要加上var。
10.2 內(nèi)存管理
JavaScript具有自動(dòng)垃圾收集機(jī)制市咆,也就是說汉操,執(zhí)行環(huán)境會(huì)負(fù)責(zé)管理代碼執(zhí)行過程中使用的內(nèi)存。其他語言比如C和C++蒙兰,必須手工跟蹤內(nèi)存使用情況磷瘤,適時(shí)的釋放,否則會(huì)造成很多問題搜变。而JavaScript則不需要這樣采缚,它會(huì)自行管理內(nèi)存分配及無用內(nèi)存的回收。
JavaScript最常用的垃圾收集方式是標(biāo)記清除挠他。垃圾收集器會(huì)在運(yùn)行的時(shí)候給存儲(chǔ)在內(nèi)存中的變量加上標(biāo)記扳抽。然后,它會(huì)去掉環(huán)境中正在使用變量的標(biāo)記殖侵,而沒有被去掉標(biāo)記的變量將被視為準(zhǔn)備刪除的變量贸呢。最后,垃圾收集器完成內(nèi)存清理工作拢军,銷毀那些帶標(biāo)記的值并回收他們所占用的內(nèi)存空間楞陷。
垃圾收集器是周期性運(yùn)行的,這樣會(huì)導(dǎo)致整個(gè)程序的性能問題茉唉。比如IE7以前的版本固蛾,它的垃圾收集器是根據(jù)內(nèi)存分配量運(yùn)行的结执,比如256個(gè)變量就開始運(yùn)行垃圾收集器,這樣魏铅,就不得不頻繁地運(yùn)行昌犹,從而降低的性能。
一般來說览芳,確保占用最少的內(nèi)存可以讓頁(yè)面獲得更好的性能。那么優(yōu)化內(nèi)存的最佳方案鸿竖,就是一旦數(shù)據(jù)不再有用沧竟,那么將其設(shè)置為null來釋放引用,這個(gè)做法叫做解除引用缚忧。這一做法適用于大多數(shù)全局變量和全局對(duì)象悟泵。
第十一章 內(nèi)置對(duì)象
內(nèi)置對(duì)象的定義是:“由JavaScript實(shí)現(xiàn)提供的、不依賴宿主環(huán)境的對(duì)象闪水,這些對(duì)象在JavaScript程序執(zhí)行之前就已經(jīng)存在了糕非。”意思就是說球榆,開發(fā)人員不必顯示地實(shí)例化內(nèi)置對(duì)象朽肥;因?yàn)樗鼈円呀?jīng)實(shí)例化了。JavaScript只定義了兩個(gè)內(nèi)置對(duì)象:Global和Math持钉。
11.1 Global對(duì)象
Global(全局)對(duì)象是JavaScript中一個(gè)特別的對(duì)象衡招,因?yàn)檫@個(gè)對(duì)象是不存在的。在JavaScript中不屬于任何其他對(duì)象的屬性和方法每强,都屬于它的屬性和方法始腾。所以,事實(shí)上空执,并不存在全局變量和全局函數(shù)浪箭;所有在全局作用域定義的變量和函數(shù),都是Global對(duì)象的屬性和方法辨绊。
因?yàn)镴avaScript沒有定義怎么調(diào)用Global對(duì)象奶栖,所以,Global.屬性或者Global.方法()都是無效的邢羔。(Web瀏覽器將Global作為window對(duì)象的一部分加以實(shí)現(xiàn))
Global對(duì)象有一些內(nèi)置的屬性和方法:
(1) URI編碼方法
URI編碼可以對(duì)鏈接進(jìn)行編碼驼抹,以便發(fā)送給瀏覽器。它們采用特殊的UTF-8編碼替換所有無效字符拜鹤,從而讓瀏覽器能夠接受和理解框冀。
encodeURI()不會(huì)對(duì)本身屬于URI的特殊字符進(jìn)行編碼,例如冒號(hào)敏簿、正斜杠明也、問號(hào)和#號(hào)宣虾;而encodeURIComponent()則會(huì)對(duì)它發(fā)現(xiàn)的任何非標(biāo)準(zhǔn)字符進(jìn)行編碼。
<script>
var parm = "http://Johnny 張";
alert(encodeURI(parm)); //Johnny%20%E5%BC%A0
alert(encodeURIComponent(parm)); //%2F%2FJohnny%20%E5%BC%A0
</script>
因?yàn)閑ncodeURIComponent()編碼比encodeURI()編碼來的更加徹底温数,一般來說encodeURIComponent()使用頻率要高一些绣硝。
使用了URI編碼過后,還可以進(jìn)行解碼撑刺,通過decodeURI()和decodeURIComponent()來進(jìn)行解碼鹉胖。
<script>
var parm = "http://Johnny 張";
var encode1 = encodeURI(parm);
var encode2 = encodeURIComponent(parm);
var decode1 = decodeURI(encode1);
var decode2 = decodeURIComponent(encode2);
alert(encode1); //Johnny%20%E5%BC%A0
alert(encode2); //%2F%2FJohnny%20%E5%BC%A0
alert(decode1);
alert(decode1);
</script>
(2) eval()方法
eval()方法主要擔(dān)當(dāng)一個(gè)字符串解析器的作用,他只接受一個(gè)參數(shù)够傍,而這個(gè)參數(shù)就是要執(zhí)行的JavaScript代碼的字符串甫菠。
<script>
eval('var num = 100'); //解析了字符串代碼
alert(num);
eval('alert(100)'); //同上
eval('function num() {return 123}'); //函數(shù)也可以
alert(num());
</script>
eval()方法的功能非常強(qiáng)大,但也非常危險(xiǎn)冕屯。因此使用的時(shí)候必須極為謹(jǐn)慎寂诱。特別是在用戶輸入數(shù)據(jù)的情況下,非常有可能導(dǎo)致程序的安全性安聘,比如代碼注入等等痰洒。
(3) Global對(duì)象屬性
Global對(duì)象包含了一些屬性:undefined、NaN浴韭、Object丘喻、Array、Function等等囱桨。
(4) window對(duì)象
Global沒有辦法直接訪問仓犬,而Web瀏覽器可以使用window對(duì)象來實(shí)現(xiàn)全局訪問。
11.2 Math對(duì)象
JavaScript還為保存數(shù)學(xué)公式和信息提供了一個(gè)對(duì)象舍肠,即Math對(duì)象搀继。與我們?cè)贘avaScript直接編寫計(jì)算功能相比,Math對(duì)象提供的計(jì)算功能執(zhí)行起來要快得多翠语。
(1) Math對(duì)象的屬性
Math對(duì)象包含的屬性大多是數(shù)學(xué)計(jì)算中可能會(huì)用到的一些特殊值叽躯。
屬性 | 說明 |
---|---|
Math.E | 自然對(duì)數(shù)的底數(shù),即常量e的值 |
Math.LN10 | 10的自然對(duì)數(shù) |
Math.LN2 | 2的自然對(duì)數(shù) |
Math.LOG2E | 以2為底e的對(duì)數(shù) |
Math.LOG10E | 以10為底e的對(duì)數(shù) |
Math.PI | PI的值 |
Math.SQRT1_2 | 1/2的平方根 |
Math.SQRT2 | 2的平方根 |
(2) min()和max()方法
Math.min()用于確定一組數(shù)值中的最小值肌括。Math.max()用于確定一組數(shù)值中的最大值点骑。
(3) 舍入方法
Math.ceil()執(zhí)行向上舍入,即它總是將數(shù)值向上舍入為最接近的整數(shù)谍夭。
Math.floor()執(zhí)行向下舍入黑滴,即它總是將數(shù)值向下舍入為最接近的整數(shù)。
Math.round()執(zhí)行標(biāo)準(zhǔn)舍入紧索,即它總是將數(shù)值四舍五入為最接近的整數(shù)袁辈。
<script>
alert(Math.ceil(25.9)); //26
alert(Math.ceil(25.5)); //26
alert(Math.ceil(25.1)); //26
alert(Math.floor(25.9)); //25
alert(Math.floor(25.5)); //25
alert(Math.floor(25.1)); //25
alert(Math.round(25.9)); //26
alert(Math.round(25.5)); //26
alert(Math.round(25.1)); //25
</script>
(4) random()方法
Math.random()方法返回介于0到1之間一個(gè)隨機(jī)數(shù),不包括0和1珠漂。如果想大于這個(gè)范圍的話晚缩,可以套用一下公式:
值 = Math.floor(Math.random() * 總數(shù) + 第一個(gè)值)
<script>
alert(Math.floor(Math.random() * 10 + 1)); //隨機(jī)產(chǎn)生1-10之間的任意數(shù)
</script>
(5) 其他方法
方法 | 說明 |
---|---|
Math.abs(num) | 返回num的絕對(duì)值 |
Math.exp(num) | 返回Math.E的num次冪 |
Math.log(num) | 返回num的自然對(duì)數(shù) |
Math.pow(num,power) | 返回num的power次冪 |
Math.sqrt(num) | 返回num的平方根 |
Math.acos(x) | 返回x的反余弦值 |
Math.asin(x) | 返回x的反正弦值 |
Math.atan(x) | 返回x的反正切值 |
Math.atan2(y,x) | 返回y/x的反正切值 |
Math.cos(x) | 返回x的余弦值 |
Math.sin(x) | 返回x的正弦值 |
Math.tan(x) | 返回x的正切值 |
第十二章 面向?qū)ο笈c原型
12.1 創(chuàng)建對(duì)象
12.1.1 new Object()
創(chuàng)建Object對(duì)象尾膊,然后給這個(gè)對(duì)象新建屬性和方法。
<script>
var car = new Object(); //創(chuàng)建一個(gè)Object對(duì)象
car.brand = "Mercedes-Benz"; //創(chuàng)建一個(gè)brand屬性并賦值
car.model = "E260L";
car.color = "White";
car.drive = function(){ //創(chuàng)建一個(gè)drive()方法并返回值
return this.brand + " " + this.model + " " + this.color + " is driving.";
};
alert(car.drive());
</script>
存在的問題:
這個(gè)創(chuàng)建了一個(gè)“Mercedes-Benz”的對(duì)象荞彼,如果需要在創(chuàng)建一個(gè)“BMW”的對(duì)象冈敛,則類似的代碼還要在寫一遍,如果需要再創(chuàng)建其他品牌車的對(duì)象鸣皂,那么類似的代碼就要寫許多份抓谴。
解決辦法:
使用工廠模式創(chuàng)建對(duì)象。
12.1.2 工廠模式
為了解決多個(gè)類似對(duì)象聲明的問題寞缝,我們可以使用一種叫做工廠模式的方法齐邦,這種方法就是為了解決實(shí)例化對(duì)象產(chǎn)生大量重復(fù)代碼的問題。
<script>
function createCarObject(brand, model, color){ //集中實(shí)例化的函數(shù)
var car = new Object();
car.brand = brand;
car.model = model;
car.color = color;
car.drive = function(){
return this.brand + " " + this.model + " " + this.color + " is driving.";
};
return car;
}
var car1 = createCarObject("Mercedes-Benz", "E260L", "white");
var car2 = createCarObject("Mercedes-Benz", "GLC260", "white");
var car3 = createCarObject("BMW", "X5", "Red");
alert(car1.drive());
alert(car2.drive());
alert(car3.drive());
</script>
存在的問題:
工廠模式解決了實(shí)例化代碼重復(fù)的問題第租,但還有一個(gè)問題,那就是識(shí)別問題我纪,因?yàn)楦緹o法搞清楚他們到底是哪個(gè)對(duì)象的實(shí)例慎宾。
<script>
function createCarObject(brand, model, color){ //集中實(shí)例化的函數(shù)
var car = new Object();
car.brand = brand;
car.model = model;
car.color = color;
car.drive = function(){
return this.brand + " " + this.model + " " + this.color + " is driving.";
};
return car;
}
var car1 = createCarObject("Mercedes-Benz", "E260L", "white");
var car2 = createCarObject("Mercedes-Benz", "GLC260", "white");
var car3 = createCarObject("BMW", "X5", "Red");
alert(typeof car1);
alert(car1 instanceof Object);
alert(typeof car2);
alert(car2 instanceof Object);
alert(typeof car3);
alert(car3 instanceof Object);
</script>
解決辦法:
采用構(gòu)造函數(shù)可用來創(chuàng)建特定的對(duì)象
12.1.3 構(gòu)造函數(shù)
使用構(gòu)造函數(shù)的方法,即解決了實(shí)例化代碼重復(fù)的問題浅悉,又解決了對(duì)象識(shí)別的問題趟据。
<script>
function Car(brand, model, color){ //構(gòu)造函數(shù)模式
this.brand = brand;
this.model = model;
this.color = color;
this.drive = function(){
return this.brand + " " + this.model + " " + this.color + " is driving.";
};
}
var car1 = new Car("Mercedes-Benz", "E260L", "white");
alert(car1.drive());
alert(typeof car1);
alert(car1 instanceof Car);
var car2 = new Car("Mercedes-Benz", "GLC260", "white");
alert(car2.drive());
alert(typeof car2);
alert(car2 instanceof Car);
var car3 = new Car("BMW", "X5", "Red");
alert(car3.drive());
alert(typeof car3);
alert(car3 instanceof Car);
</script>
使用了構(gòu)造函數(shù)的方法,和使用工廠模式的方法的不同之處如下:
(1) 構(gòu)造函數(shù)方法沒有顯示的創(chuàng)建對(duì)象(new Object())术健;
(2) 直接將屬性和方法賦值給this對(duì)象汹碱;
(3) 沒有return語句。
構(gòu)造函數(shù)的方法有一些規(guī)范:
(1) 函數(shù)名和實(shí)例化構(gòu)造名相同且大寫荞估;
(2) 通過構(gòu)造函數(shù)創(chuàng)建對(duì)象咳促,必須使用new運(yùn)算符。
構(gòu)造函數(shù)和普通函數(shù)的唯一區(qū)別勘伺,就是他們調(diào)用方式不同跪腹。只不過,構(gòu)造函數(shù)也是函數(shù)飞醉,必須用new運(yùn)算符來調(diào)用冲茸,否則就是普通函數(shù)。
<script>
function Car(brand, model, color){ //集中實(shí)例化的函數(shù)
this.brand = brand;
this.model = model;
this.color = color;
this.drive = function(){
return this.brand + " " + this.model + " " + this.color + " is driving.";
};
}
function sayHello(fullName){
return "Hello " + fullName;
}
var car1 = new Car("Mercedes-Benz", "E260L", "white");
alert(car1.drive());
alert(sayHello("Johnny"));
</script>
探討構(gòu)造函數(shù)內(nèi)部的方法(或函數(shù))的問題缅帘。
<script>
function Car(brand, model, color){ //集中實(shí)例化的函數(shù)
this.brand = brand;
this.model = model;
this.color = color;
this.drive = function(){
return this.brand + " " + this.model + " " + this.color + " is driving.";
};
}
var car1 = new Car("Mercedes-Benz", "E260L", "white");
var car2 = new Car("Mercedes-Benz", "GLC260", "white");
alert(car1.brand === car2.brand); //true, 類型內(nèi)容均相等
alert(car1.model === car2.model); //false, 類型相等內(nèi)容不等
alert(car1.color === car2.color); //true, 類型內(nèi)容均相等
alert(car1.drive === car2.drive); //false, 引用地址不相等
</script>
12.2 原型
我們創(chuàng)建的每個(gè)函數(shù)都有一個(gè)原型屬性(prototype)轴术,這個(gè)屬性是一個(gè)對(duì)象,它的用途是包含可以由特定類型的所有實(shí)例共享的屬性和方法钦无。使用原型的好處可以讓所有對(duì)象實(shí)例共享它所包含的屬性和方法逗栽。也就是說,不必在構(gòu)造函數(shù)中定義對(duì)象信息铃诬,而是可以直接將這些信息添加到原型中祭陷。
12.2.1 使用構(gòu)造函數(shù)創(chuàng)建原型對(duì)象
<script>
//使用聲明構(gòu)造函數(shù)的方式苍凛,在原型中添加屬性和方法
function SaloonCar(){}
SaloonCar.prototype.carType = "家用型轎車";
SaloonCar.prototype.drive = function(){
return "Saloon car is driving.";
};
//在構(gòu)造函數(shù)中添加屬性和方法
function Suv(brand, model){
this.brand = brand;
this.model = model;
this.drive = function(){
return this.brand + " " + this.model + " is driving.";
};
}
var bora = new SaloonCar();
var mazda = new SaloonCar();
alert(bora.drive === mazda.drive); //true
var bmwX5 = new Suv("BMW", "X5");
var benzGlc = new Suv("Benz", "GLC260");
alert(bmwX5.drive === benzGlc.drive); //false
</script>
在原型模式聲明中,多了一個(gè)proto屬性兵志,這個(gè)屬性都是創(chuàng)建對(duì)象時(shí)自動(dòng)生成的醇蝴。proto屬性是實(shí)例指向原型對(duì)象的指針,它的作用就是指向構(gòu)造函數(shù)的原型屬性constructor想罕。通過這個(gè)屬性悠栓,就可以訪問到原型里的屬性和方法了。
說明:IE瀏覽器在腳本訪問proto會(huì)不能識(shí)別按价,火狐和谷歌瀏覽器及其他某些瀏覽器均能識(shí)別惭适。雖然可以輸出,但無法獲取內(nèi)部信息楼镐。
原型模式的執(zhí)行流程:
Step1:先查找構(gòu)造函數(shù)實(shí)例里的屬性或方法癞志,如果有,立刻返回框产;
Step2:如果構(gòu)造函數(shù)實(shí)例里沒有凄杯,則去它的原型對(duì)象里找,如果有秉宿,就返回戒突;
通過原型添加的值類型的屬性,其值不能被重寫:
<script>
//使用聲明構(gòu)造函數(shù)的方式描睦,在原型中添加屬性和方法
function SaloonCar(){}
SaloonCar.prototype.carType = "家用型轎車";
SaloonCar.prototype.drive = function(){
return "Saloon car is driving.";
};
var bora = new SaloonCar();
bora.carType = "商務(wù)用車";
alert(bora.carType);
var mazda = new SaloonCar();
alert(mazda.carType);
</script>
內(nèi)置方法和操作符:
isPrototypeOf()
判斷一個(gè)對(duì)象是否指向了該構(gòu)造函數(shù)的原型對(duì)象膊存。
<script>
//使用聲明構(gòu)造函數(shù)的方式,在原型中添加屬性和方法
function SaloonCar(){}
SaloonCar.prototype.carType = "家用型轎車";
SaloonCar.prototype.drive = function(){
return "Saloon car is driving.";
};
var bora = new SaloonCar();
alert(SaloonCar.prototype.isPrototypeOf(bora));
</script>
hasOwnProperty()
判斷一個(gè)屬性是構(gòu)造函數(shù)中的屬性而非原型中的屬性忱叭。
<script>
//使用聲明構(gòu)造函數(shù)的方式隔崎,在原型中添加屬性和方法
function SaloonCar(){}
SaloonCar.prototype.carType = "家用型轎車";
SaloonCar.prototype.drive = function(){
return "Saloon car is driving.";
};
//在構(gòu)造函數(shù)中添加屬性和方法
function Suv(brand, model){
this.brand = brand;
this.model = model;
this.drive = function(){
return this.brand + " " + this.model + " is driving.";
};
}
var bora = new SaloonCar();
alert(bora.hasOwnProperty("carType")); //false
var benzGlc = new Suv("Benz", "GLC260");
alert(benzGlc.hasOwnProperty("brand")); //true
</script>
in
判斷指定屬性是否在對(duì)象中,無論是構(gòu)造函數(shù)中定義的還是原型定義的屬性窑多。
<script>
//使用聲明構(gòu)造函數(shù)的方式仍稀,在原型中添加屬性和方法
function SaloonCar(){}
SaloonCar.prototype.carType = "家用型轎車";
SaloonCar.prototype.drive = function(){
return "Saloon car is driving.";
};
//在構(gòu)造函數(shù)中添加屬性和方法
function Suv(brand, model){
this.brand = brand;
this.model = model;
this.drive = function(){
return this.brand + " " + this.model + " is driving.";
};
}
var bora = new SaloonCar();
alert("carType" in bora);//true
var benzGlc = new Suv("Benz", "GLC260");
alert("brand" in benzGlc);//true
</script>
12.2.2 使用字面量創(chuàng)建原型對(duì)象
為了讓屬性和方法更好的體現(xiàn)封裝的效果,并且減少不必要的輸入埂息,原型的創(chuàng)建可以使用字面量的方式技潘。使用構(gòu)造函數(shù)創(chuàng)建原型對(duì)象和使用字面量創(chuàng)建原型對(duì)象在使用上基本相同,但還是有一些區(qū)別千康,字面量創(chuàng)建的方式使用constructor屬性不會(huì)指向?qū)嵗碛模鴷?huì)指向Object,構(gòu)造函數(shù)創(chuàng)建的方式則相反拾弃。
<script>
//使用字面量方式聲明原型屬性和方法
function SaloonCar(){}
SaloonCar.prototype = {
carType: "家用型轎車",
drive: function(){
return "Saloon car is driving.";
}
};
var bora = new SaloonCar();
alert(bora instanceof SaloonCar);
alert(bora instanceof Object);
alert(bora.constructor === SaloonCar); //字面量方式值桩,返回false,否則豪椿,true
alert(bora.constructor === Object); //字面量方式奔坟,返回true携栋,否則,false
</script>
如果想讓字面量方式的constructor指向?qū)嵗龑?duì)象咳秉,那么可以這么做:
SaloonCar.prototype = {
constructor: SaloonCar,
carType: "家用型轎車",
drive: function(){
return "Saloon car is driving.";
}
};
說明:使用字面量方式創(chuàng)建的原型對(duì)象為什么constructor會(huì)指向Object婉支?那是因?yàn)镾aloonCar.prototype={};這種寫法其實(shí)就是創(chuàng)建了一個(gè)新對(duì)象。而每創(chuàng)建一個(gè)對(duì)象澜建,就會(huì)同時(shí)創(chuàng)建它prototype屬性向挖,這個(gè)對(duì)象也會(huì)自動(dòng)獲取constructor屬性。所以炕舵,新對(duì)象的constructor重寫了SaloonCar原來的constructor何之,因此會(huì)指向新對(duì)象,那個(gè)新對(duì)象沒有指定構(gòu)造函數(shù)咽筋,那么就默認(rèn)為Object溶推。
原型的聲明是有先后順序的,所以奸攻,重寫的原型會(huì)切斷之前的原型悼潭,所以不要重復(fù)聲明原型。
<script>
//使用字面量方式聲明原型屬性和方法
function SaloonCar(){}
SaloonCar.prototype = {
constructor: SaloonCar,
carType: "家用型轎車",
drive: function(){
return "Saloon car is driving.";
}
};
SaloonCar.prototype = {
color: "White"
};
var bora = new SaloonCar();
alert(bora.drive());//報(bào)錯(cuò)
</script>
原型模式創(chuàng)建對(duì)象也有自己的缺點(diǎn)舞箍,它省略了構(gòu)造函數(shù)傳參初始化這一過程,帶來的缺點(diǎn)就是初始化的值都是一致的皆疹。而原型最大的缺點(diǎn)就是它最大的優(yōu)點(diǎn)疏橄,那就是共享。
原型中所有屬性是被很多實(shí)例共享的略就,共享對(duì)于函數(shù)非常合適捎迫,對(duì)于包含值類型的屬性也還可以。但如果屬性包含引用類型表牢,就存在一定的問題:
<script>
function Student(){};
Student.prototype = {
constructor: Student,
family: ["父親", "母親"],
showFamily: function(){
return this.family;
}
};
var s1 = new Student();
s1.family.push("哥哥");
alert(s1.showFamily()); //父親窄绒,母親,哥哥
var s2 = new Student();
alert(s2.showFamily()); //父親崔兴,母親彰导,哥哥
</script>
為了解決構(gòu)造傳參和共享問題,可以使用構(gòu)造函數(shù)+原型模式:
<script>
function Student(fullName, age) { //不共享的使用構(gòu)造函數(shù)
this.fullName = fullName;
this.age = age;
this.family = ['父親', '母親'];
};
Student.prototype = { //共享的使用原型模式
constructor : Student,
showFamily : function () {
return this.fullName + " " + this.age + "歲敲茄,家庭成員:" + this.family;
}
};
var s1 = new Student("佟大為", 32);
s1.family.push("哥哥");
alert(s1.showFamily()); //父親位谋,母親, 哥哥
var s2 = new Student("馬伊琍", 20);
alert(s2.showFamily()); //父親,母親
var s3 = new Student("趙麗穎", 19);
s3.family.push("姐姐");
alert(s3.showFamily()); //父親堰燎,母親, 姐姐
</script>
說明:這種構(gòu)造函數(shù)+原型的模式很好的解決了傳參和引用共享的大難題掏父。是創(chuàng)建對(duì)象比較好的方法。
原型模式秆剪,不管你是否調(diào)用了原型中的共享方法赊淑,它都會(huì)初始化原型中的方法爵政,并且在聲明一個(gè)對(duì)象時(shí),構(gòu)造函數(shù)+原型部分讓人感覺又很怪異陶缺,最好就是把構(gòu)造函數(shù)和原型封裝到一起钾挟。為了解決這個(gè)問題,我們可以使用動(dòng)態(tài)原型模式(實(shí)際項(xiàng)目中使用的模式)组哩。
<script>
function Student(fullName, age) { //不共享的使用構(gòu)造函數(shù)
this.fullName = fullName;
this.age = age;
this.family = ['父親', '母親'];
if(typeof this.showFamily != "function"){
Student.prototype.showFamily = function(){ //共享的使用原型模式
return this.fullName + " " + this.age + "歲等龙,家庭成員:" + this.family;
};
}
};
var s1 = new Student("佟大為", 32);
s1.family.push("哥哥");
alert(s1.showFamily()); //父親,母親, 哥哥
var s2 = new Student("馬伊琍", 20);
alert(s2.showFamily()); //父親伶贰,母親
var s3 = new Student("趙麗穎", 19);
s3.family.push("姐姐");
alert(s3.showFamily()); //父親蛛砰,母親, 姐姐
</script>
說明:
- 當(dāng)?shù)谝淮握{(diào)用構(gòu)造函數(shù)時(shí),showFamily()方法發(fā)現(xiàn)不存在黍衙,然后初始化原型泥畅。當(dāng)?shù)诙握{(diào)用,就不會(huì)初始化琅翻,并且第二次創(chuàng)建新對(duì)象位仁,原型也不會(huì)再初始化了。這樣及得到了封裝方椎,又實(shí)現(xiàn)了原型方法共享聂抢,并且屬性都保持獨(dú)立。
- 不可以再使用字面量的方式重寫原型棠众,因?yàn)闀?huì)切斷實(shí)例和新原型之間的聯(lián)系琳疏。
12.2.3 繼承
繼承是面向?qū)ο笾幸粋€(gè)比較核心的概念。其他正統(tǒng)面向?qū)ο笳Z言都會(huì)用兩種方式實(shí)現(xiàn)繼承:一個(gè)是接口實(shí)現(xiàn)闸拿,一個(gè)是繼承空盼。而JavaScript只支持繼承,不支持接口實(shí)現(xiàn)新荤,而實(shí)現(xiàn)繼承的方式依靠原型鏈完成揽趾。
<script>
function Product(){
this.color = "White";
}
function Cellphone(){
this.name = "iphone"
}
Cellphone.prototype = new Product();
var cellphone = new Cellphone();
alert(cellphone.name);
alert(cellphone.color);
</script>
在JavaScript里,被繼承的函數(shù)稱為超類型(其他語言成為父類)苛骨,繼承的函數(shù)稱為子類型(其他語言成為派生類)篱瞎。繼承也有之前問題,比如字面量重寫原型會(huì)中斷關(guān)系痒芝,使用引用類型的原型奔缠,并且子類型還無法給超類型傳遞參數(shù)。
為了解決引用共享和超類型無法傳參的問題吼野,我們可以采用對(duì)象冒充(偽造對(duì)象校哎、經(jīng)典繼承)的方法來解決這兩種問題。
<script>
function Product(name){
this.manufacturers = ["Apple", "Sumsung"];
this.name = name;
}
function Cellphone(name, brand, model){
Product.call(this, name)
this.brand = brand;
this.model = model;
}
var product1 = new Cellphone("cellphone", "letv", "1Pro");
product1.manufacturers.push("letv");
alert(product1.name + ": " + product1.brand + product1.model + "\n" + product1.manufacturers);
var product2 = new Cellphone("cellphone", "meizu", "魅藍(lán)3");
product2.manufacturers.push("meizu");
alert(product2.name + ": " + product2.brand + product2.model + "\n" + product2.manufacturers);
</script>
借用構(gòu)造函數(shù)雖然解決了剛才兩種問題,但沒有原型闷哆,復(fù)用則無從談起腰奋。所以,我們需要原型鏈+借用構(gòu)造函數(shù)的模式抱怔,這種模式成為組合繼承劣坊。
<script>
function Product(name){
this.manufacturers = ["Apple", "Sumsung"];
this.name = name;
if(typeof this.show != "function"){
Product.prototype.show = function(){//方法放到原型中,使其每次實(shí)例化時(shí)方法地址保持一致
alert("The product is:" + this.name);
}
}
}
function Cellphone(name, brand, model){
Product.call(this, name)
this.brand = brand;
this.model = model;
}
function Pad(name, brand, model){
Product.call(this, name);
this.brand = brand;
this.model = model;
}
Cellphone.prototype = new Product();
Pad.prototype = new Product();
var product1 = new Cellphone("cellphone", "iphone", "6puls");
product1.show();
var product2 = new Pad("pad", "ipad", "air");
product2.show();
alert(product1.show === product2.show);//true
</script>
組合式繼承是JavaScript最常用的繼承模式屈留。
第十三章 匿名函數(shù)和閉包
13.1 匿名函數(shù)
匿名函數(shù)就是沒有名字的函數(shù)局冰。
(1)普通函數(shù)(有名字的函數(shù))
function showCarInfo(car){
var carInfo = "Car brand:" + car.brand + "\n" +
"Car model:" + car.model + "\n" +
"Car color:" + car.color;
alert(carInfo);
}
(2)匿名函數(shù)(沒有名字的函數(shù))
function(){
alert("hello.");
}
如何執(zhí)行匿名函數(shù):
方法1:通過表達(dá)式自我執(zhí)行
(function(){
alert("hello.");
})();
方法2:把匿名函數(shù)賦值給變量
var show = function(){
alert("hello.");
};
show();
方法3:函數(shù)里的匿名函數(shù)
function show(){
return function(){
return "hello.";
}
}
alert(show()());
實(shí)際項(xiàng)目中使用場(chǎng)景:
場(chǎng)景一、回掉函數(shù)
場(chǎng)景二灌危、閉包
13.2 閉包
閉包是指有權(quán)訪問另一個(gè)函數(shù)作用域中的變量的函數(shù)康二,創(chuàng)建閉包的常見的方式,就是在一個(gè)函數(shù)內(nèi)部創(chuàng)建另一個(gè)函數(shù)勇蝙,通過另一個(gè)函數(shù)訪問這個(gè)函數(shù)的局部變量沫勿。
使用閉包有一個(gè)優(yōu)點(diǎn),也是它的缺點(diǎn):就是可以把局部變量駐留在內(nèi)存中味混,可以避免使用全局變量产雹。(全局變量污染導(dǎo)致應(yīng)用程序不可預(yù)測(cè)性,每個(gè)模塊都可調(diào)用必將引來災(zāi)難翁锡,所以推薦使用私有的蔓挖,封裝的局部變量)。
function show(){
var num = 0;
return function(){
num++;
return num;
}
}
var s = show();
alert(s()); //1
alert(s()); //2
alert(s()); //3
說明:由于閉包里作用域返回的局部變量資源不會(huì)被立刻銷毀回收馆衔,所以可能會(huì)占用更多的內(nèi)存时甚。過度使用閉包會(huì)導(dǎo)致性能下降,建議在非常有必要的時(shí)候才使用閉包哈踱。
第十四章 BOM操作
BOM(Browser Object Model)也叫瀏覽器對(duì)象模型,它提供了很多對(duì)象梨熙,用于訪問瀏覽器的功能开镣。BOM缺少規(guī)范,每個(gè)瀏覽器提供商又按照自己想法去擴(kuò)展它咽扇,那么瀏覽器共有對(duì)象就成了事實(shí)的標(biāo)準(zhǔn)邪财。所以,BOM本身是沒有標(biāo)準(zhǔn)的或者還沒有哪個(gè)組織去標(biāo)準(zhǔn)它。
14.1 window對(duì)象
BOM的核心對(duì)象是window,它表示瀏覽器的一個(gè)實(shí)例竿报。window對(duì)象處于JavaScript結(jié)構(gòu)的最頂層赊豌,對(duì)于每個(gè)打開的窗口,系統(tǒng)都會(huì)自動(dòng)為其定義 window 對(duì)象映跟。
(1) window對(duì)象的屬性
屬性 | 含義 |
---|---|
closed | 當(dāng)窗口關(guān)閉時(shí)為真 |
defaultStatus | 窗口底部狀態(tài)欄顯示的默認(rèn)狀態(tài)消息 |
document | 窗口中當(dāng)前顯示的文檔對(duì)象 |
frames | 窗口中的框架對(duì)象數(shù)組 |
history | 保存有窗口最近加載的URL |
length | 窗口中的框架數(shù) |
location | 當(dāng)前窗口的URL |
name | 窗口名 |
offscreenBuffering | 用于繪制新窗口內(nèi)容并在完成后復(fù)制已存在的內(nèi)容,控制屏幕更新 |
opener | 打開當(dāng)前窗口的窗口 |
parent | 指向包含另一個(gè)窗口的窗口(由框架使用) |
screen | 顯示屏幕相關(guān)信息尉咕,如高度绊袋、寬度(以像素為單位) |
self | 指示當(dāng)前窗口毕匀。 |
status | 描述由用戶交互導(dǎo)致的狀態(tài)欄的臨時(shí)消息 |
top | 包含特定窗口的最頂層窗口(由框架使用) |
window | 指示當(dāng)前窗口,與self等效 |
(2) window對(duì)象的方法
方法 | 功能 |
---|---|
alert(text) | 創(chuàng)建一個(gè)警告對(duì)話框癌别,顯示一條信息 |
blur() | 將焦點(diǎn)從窗口移除 |
clearInterval(interval) | 清除之前設(shè)置的定時(shí)器間隔 |
clearTimeOut(timer) | 清除之前設(shè)置的超時(shí) |
close() | 關(guān)閉窗口 |
confirm() | 創(chuàng)建一個(gè)需要用戶確認(rèn)的對(duì)話框 |
focus() | 將焦點(diǎn)移至窗口 |
open(url,name,[options]) | 打開一個(gè)新窗口并返回新window對(duì)象 |
prompt(text,defaultInput) | 創(chuàng)建一個(gè)對(duì)話框要求用戶輸入信息 |
scroll(x,y) | 在窗口中滾動(dòng)到一個(gè)像素點(diǎn)的位置 |
setInterval(expression,milliseconds) | 經(jīng)過指定時(shí)間間隔計(jì)算一個(gè)表達(dá)式 |
setInterval(function,millisenconds,[arguments]) | 經(jīng)過指定時(shí)間間隔后調(diào)用一個(gè)函數(shù) |
setTimeout(expression,milliseconds) | 在定時(shí)器超過后計(jì)算一個(gè)表達(dá)式 |
setTimeout(expression,milliseconds,[arguments]) | 在定時(shí)器超過時(shí)后計(jì)算一個(gè)函數(shù) |
print() | 調(diào)出打印對(duì)話框 |
find() | 調(diào)出查找對(duì)話框 |
window下的屬性和方法皂岔,可以使用window.屬性、window.方法()或者直接屬性展姐、方法()的方式調(diào)用躁垛。例如:window.alert()和alert()是一樣的。
14.2 location對(duì)象
location是BOM對(duì)象之一圾笨,它提供了與當(dāng)前窗口中加載的文檔有關(guān)的信息教馆,還提供了一些導(dǎo)航功能。事實(shí)上墅拭,location對(duì)象是window對(duì)象的屬性活玲,也是document對(duì)象的屬性;所以window.location和document.location等效谍婉。
(1) location對(duì)象的屬性
屬性 | 描述的URL內(nèi)容 |
---|---|
hash | 如果該部分存在舒憾,表示錨點(diǎn)部分 |
host | 主機(jī)名:端口號(hào) |
hostname | 主機(jī)名 |
href | 整個(gè)URL |
pathname | 路徑名 |
port | 端口號(hào) |
protocol | 協(xié)議部分 |
search | 查詢字符串 |
(2) location對(duì)象的方法
方法 | 功能 |
---|---|
assign() | 跳轉(zhuǎn)到指定頁(yè)面,與href等效 |
reload() | 重載當(dāng)前URL |
repalce() | 用新的URL替換當(dāng)前頁(yè)面 |
14.3 history對(duì)象
history對(duì)象是window對(duì)象的屬性穗熬,它保存著用戶上網(wǎng)的記錄镀迂,從窗口被打開的那一刻算起。
(1) history對(duì)象的屬性
屬性 | 描述的URL內(nèi)容 |
---|---|
length | history對(duì)象中的記錄數(shù) |
(2) history對(duì)象的方法
方法 | 功能 |
---|---|
back() | 前往瀏覽器歷史條目前一個(gè)URL唤蔗,類似后退 |
forward() | 前往瀏覽器歷史條目下一個(gè)URL探遵,類似前進(jìn) |
go(num) | 瀏覽器在history對(duì)象中向前或向后 |
第十五章 DOM操作
DOM(Document Object Model)即文檔對(duì)象模型,針對(duì)HTML和XML文檔的API(應(yīng)用程序接口)妓柜。DOM描繪了一個(gè)層次化的節(jié)點(diǎn)樹箱季,運(yùn)行開發(fā)人員添加、移除和修改頁(yè)面的某一部分棍掐。
15.1 DOM介紹
(1) 節(jié)點(diǎn)
加載HTML頁(yè)面時(shí)藏雏,Web瀏覽器生成一個(gè)樹型結(jié)構(gòu),用來表示頁(yè)面內(nèi)部結(jié)構(gòu)作煌。DOM將這種樹型結(jié)構(gòu)理解為由節(jié)點(diǎn)組成掘殴。
從上圖的樹型結(jié)構(gòu),我們理解幾個(gè)概念粟誓,html標(biāo)簽沒有父輩奏寨,沒有兄弟,所以html標(biāo)簽為根標(biāo)簽鹰服。head標(biāo)簽是html子標(biāo)簽病瞳,meta和title標(biāo)簽之間是兄弟關(guān)系揽咕。如果把每個(gè)標(biāo)簽當(dāng)作一個(gè)節(jié)點(diǎn)的話,那么這些節(jié)點(diǎn)組合成了一棵節(jié)點(diǎn)樹(后面我們經(jīng)常把標(biāo)簽稱作為元素仍源,是一個(gè)意思)心褐。
(2) 節(jié)點(diǎn)種類
節(jié)點(diǎn)種類分為三種,元素節(jié)點(diǎn)笼踩、文本節(jié)點(diǎn)逗爹、屬性節(jié)點(diǎn)。
<div title="屬性節(jié)點(diǎn)">測(cè)試div</div>
DOM操作請(qǐng)參照后續(xù)jQuery課程嚎于。
第十六章 JavaScript事件
16.1 事件介紹
JavaScript事件是由訪問Web頁(yè)面的用戶引起的一系列操作掘而,例如:用戶點(diǎn)擊。當(dāng)用戶執(zhí)行某些操作的時(shí)候于购,再去執(zhí)行一系列代碼袍睡。事件一般是用于瀏覽器和用戶操作進(jìn)行交互。最早是IE和Netscape Navigator中出現(xiàn)肋僧,作為分擔(dān)服務(wù)器端運(yùn)算負(fù)載的一種手段斑胜。直到幾乎所有的瀏覽器都支持事件處理。而DOM2級(jí)規(guī)范開始嘗試以一種復(fù)合邏輯的方式標(biāo)準(zhǔn)化DOM事件嫌吠。IE9止潘、Firefox、Opera辫诅、Safari和Chrome全都已經(jīng)實(shí)現(xiàn)了“DOM2級(jí)事件”模塊的核心部分凭戴。IE8之前瀏覽器仍然使用其專有事件模型。
JavaScript有三種事件模型:內(nèi)聯(lián)模型炕矮、腳本模型和DOM2模型么夫。
16.2 內(nèi)聯(lián)模型
這種模型是傳統(tǒng)且單一的處理事件的方法。在內(nèi)聯(lián)模型中肤视,事件處理函數(shù)是HTML標(biāo)簽的一個(gè)屬性档痪,用于處理指定事件。雖然內(nèi)聯(lián)在早期使用較多邢滑,但它是和HTML混寫的腐螟,并沒有與HTML分離,現(xiàn)在已很少使用殊鞭。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JavaScript事件</title>
</head>
<script>
function hello(n){
alert("hello " + n);
}
</script>
<body>
<button onclick="alert('hello.')">內(nèi)聯(lián)事件(嵌入內(nèi)容)</button>
<button onclick="hello('Johnny')">內(nèi)聯(lián)事件(調(diào)用函數(shù))</button>
</body>
</html>
16.3 腳本模型
由于內(nèi)聯(lián)模型違反了HTML與JavaScript代碼層次分離的原則。為了解決這個(gè)問題尼桶,我們可以在JavaScript中處理事件操灿。這種處理方式就是腳本模型。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JavaScript事件</title>
</head>
<script>
window.onload = function(){
var btn = document.getElementById("btnOnclick");
btn.onclick = function(){
alert("hello.");
};
};
</script>
<body>
<button id="btnOnclick">腳本模型</button>
</body>
</html>
16.4 事件處理函數(shù)
JavaScript可以處理的事件類型為:鼠標(biāo)事件泵督、鍵盤事件趾盐、HTML事件。
JavaScript事件處理函數(shù)及其使用列表
事件處理函數(shù) | 影響的元素 | 何時(shí)發(fā)生 |
---|---|---|
onabort | 圖像 | 當(dāng)圖像加載被中斷時(shí) |
onblur | 窗口、框架救鲤、所有表單對(duì)象 | 當(dāng)焦點(diǎn)從對(duì)象上移開時(shí) |
onchange | 輸入框久窟,選擇框和文本區(qū)域 | 當(dāng)改變一個(gè)元素的值且失去焦點(diǎn)時(shí) |
onclick | 鏈接、按鈕本缠、表單對(duì)象斥扛、圖像映射區(qū)域 | 當(dāng)用戶單擊對(duì)象時(shí) |
ondblclick | 鏈接、按鈕丹锹、表單對(duì)象 | 當(dāng)用戶雙擊對(duì)象時(shí) |
ondragdrop | 窗口 | 當(dāng)用戶將一個(gè)對(duì)象拖放到瀏覽器窗口時(shí) |
onError | 腳本 | 當(dāng)腳本中發(fā)生語法錯(cuò)誤時(shí) |
onfocus | 窗口稀颁、框架、所有表單對(duì)象 | 當(dāng)單擊鼠標(biāo)或者將鼠標(biāo)移動(dòng)聚焦到窗口或框架時(shí) |
onkeydown | 文檔楣黍、圖像匾灶、鏈接、表單 | 當(dāng)按鍵被按下時(shí) |
onkeypress | 文檔租漂、圖像阶女、鏈接、表單 | 當(dāng)按鍵被按下然后松開時(shí) |
onkeyup | 文檔哩治、圖像秃踩、鏈接、表單 | 當(dāng)按鍵被松開時(shí) |
onload | 主題锚扎、框架集吞瞪、圖像 | 文檔或圖像加載后 |
onunload | 主體、框架集 | 文檔或框架集卸載后 |
onmouseout | 鏈接 | 當(dāng)圖標(biāo)移除鏈接時(shí) |
onmouseover | 鏈接 | 當(dāng)鼠標(biāo)移到鏈接時(shí) |
onmove | 窗口 | 當(dāng)瀏覽器窗口移動(dòng)時(shí) |
onreset | 表單復(fù)位按鈕 | 單擊表單的reset按鈕 |
onresize | 窗口 | 當(dāng)選擇一個(gè)表單對(duì)象時(shí) |
onselect | 表單元素 | 當(dāng)選擇一個(gè)表單對(duì)象時(shí) |
onsubmit | 表單 | 當(dāng)發(fā)送表格到服務(wù)器時(shí) |
實(shí)際項(xiàng)目中一般使用jQuery來實(shí)現(xiàn)腳本模式添加事件驾孔,詳細(xì)請(qǐng)參照jQuery課程芍秆。
第十七章 表單處理
為了分擔(dān)服務(wù)器處理表單的壓力,JavaScript提供了一些解決方案翠勉,從而大大打破了處處依賴服務(wù)器的局面妖啥。
實(shí)際項(xiàng)目中一般使用jQuery來處理表單,詳細(xì)請(qǐng)參照jQuery課程对碌。
第十八章 錯(cuò)誤處理與調(diào)試
良好的錯(cuò)誤處理機(jī)制可以及時(shí)的提醒用戶荆虱,知道發(fā)生了什么事,而不會(huì)驚慌失措朽们。為此怀读,作為開發(fā)人員,我們必須理解在處理JavaScript錯(cuò)誤的時(shí)候骑脱,都有哪些手段和工具可以利用菜枷。我們可以使用try-catch語句來捕獲可能會(huì)發(fā)生的錯(cuò)誤并進(jìn)行處理。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>原型</title>
</head>
<script>
window.onload = function(){
var btn = document.getElementById("btnOnclick");
btn.onclick = function(){
try{
var arr = new Array[-5];
}catch(err){
alert(err.message);
}
};
};
</script>
<body>
<input type="text" id="input-number" placeholder="請(qǐng)輸入日期" />
<button id="btnOnclick">腳本模型</button>
</body>
</html>
善用try-catch
在明明知道某個(gè)地方會(huì)產(chǎn)生錯(cuò)誤叁丧,可以通過修改代碼來解決的地方啤誊,是不適合用try-catch的岳瞭。或者是那種不同瀏覽器兼容性錯(cuò)誤導(dǎo)致錯(cuò)誤的也不太適合蚊锹,因?yàn)榭梢酝ㄟ^判斷瀏覽器或者判斷這款瀏覽器是否存在此屬性和方法來解決瞳筏。
常規(guī)錯(cuò)誤和這種瀏覽器兼容錯(cuò)誤,我們都不建議使用try-catch牡昆。因?yàn)槌R?guī)錯(cuò)誤可以修改代碼即可解決姚炕,瀏覽器兼容錯(cuò)誤,可以通過普通if判斷即可迁杨。并且try-catch比一般語句消耗資源更多钻心,負(fù)擔(dān)更大。所以铅协,在萬不得已捷沸,無法修改代碼,不能通過普通判斷的情況下才去使用try-catch狐史,比如后面的Ajax技術(shù)痒给。
第十九章 Cookie
19.1 Cookie介紹
隨著Web越來越復(fù)雜,開發(fā)者急切的需要能夠本地化存儲(chǔ)的腳本功能骏全。這個(gè)時(shí)候苍柏,第一個(gè)出現(xiàn)的方案:cookie誕生了。cookie的意圖是姜贡,在本地的客戶端的磁盤上以很小的文件形式保存數(shù)據(jù)试吁。
cookie也叫HTTP Cookie,最初是客戶端與服務(wù)器端進(jìn)行會(huì)話使用的楼咳。比如熄捍,會(huì)員登錄,下次回訪網(wǎng)站時(shí)無須登錄了母怜;或者是購(gòu)物車余耽,購(gòu)買的商品沒有及時(shí)付款,過兩天發(fā)現(xiàn)購(gòu)物車?yán)镞€有之前的商品列表苹熏。
HTTP Cookie要求服務(wù)器對(duì)任意HTTP請(qǐng)求發(fā)送Set-Cookie碟贾,因此,Cookie的處理原則上需要在服務(wù)器環(huán)境下進(jìn)行轨域。當(dāng)然袱耽,現(xiàn)在大部分瀏覽器在客戶端也能實(shí)現(xiàn)Cookie的生成和獲取。(目前Chrome不可以在客戶端操作干发,其他瀏覽器均可)
cookie的組成:
cookie由名/值(鍵值對(duì))形式的文本組成:name=value朱巨。完整格式為:
name=value; [expires=date]; [path=path]; [domain=somewhere.com]; [secure]
中括號(hào)是可選,name=value是必選铐然。
expires=date 失效時(shí)間蔬崩,如果沒有聲明,則為瀏覽器關(guān)閉后即失效搀暑。聲明了失效時(shí)間沥阳,那么時(shí)間到期后方能失效。
path=path 訪問路徑自点,當(dāng)設(shè)置了路徑桐罕,那么只有設(shè)置的那個(gè)路徑文件才可以訪問cookie。
domain=domain 訪問域名桂敛,用于限制只有設(shè)置的域名才可以訪問功炮,那么沒有設(shè)置,會(huì)默認(rèn)限制為創(chuàng)建cookie的域名术唬。
secure 安全設(shè)置薪伏,指明必須通過安全的通信通道來傳輸(HTTPS)才能獲取cookie。
具體Cookie的操作一般使用jQuery來實(shí)現(xiàn)粗仓,請(qǐng)參照jQuery課程嫁怀。
19.2 Cookie的局限性
Cookie雖然在持久保存客戶端用戶數(shù)據(jù)提供了方便,分擔(dān)了服務(wù)器存儲(chǔ)的負(fù)擔(dān)借浊。但是還有很多局限性的塘淑。
(1) 每個(gè)特定的域名下最多生成20個(gè)cookie(根據(jù)不同的瀏覽器有所區(qū)別)
- IE7和之后的版本最多可以50個(gè)cookie。IE7最初也只能20個(gè)蚂斤,之后因被升級(jí)不定后增加了存捺。
- Firefox最多50個(gè)cookie
- Opera最多30個(gè)cookie
- Safari和Chrome沒有做硬性限制。
為了更好的兼容性曙蒸,所以按照最低的要求來捌治,也就是最多不得超過20個(gè)cookie。當(dāng)超過指定的 cookie時(shí)逸爵,瀏覽器會(huì)清理掉早期的cookie具滴。IE和Opera會(huì)清理近期最少使用的cookie,F(xiàn)irefox會(huì)隨機(jī)清理cookie师倔。
(2) Cookie的最大大約為4096字節(jié)(4k)构韵,為了更好的兼容性,一般不能超過4095字節(jié)即可趋艘。
(3) Cookie存儲(chǔ)在客戶端的文本文件疲恢,所以特別重要和敏感的數(shù)據(jù)是不建議保存在Cookie的。比如銀行卡號(hào)瓷胧,用戶密碼等显拳。
第二十章 XML
20.1 XML簡(jiǎn)介
XML是可擴(kuò)展標(biāo)記語言,被設(shè)計(jì)用來傳輸和存儲(chǔ)數(shù)據(jù)搓萧。XML與HTML的區(qū)別如下:
- XML用來傳輸和存儲(chǔ)數(shù)據(jù)杂数,HTML被設(shè)計(jì)用來顯示數(shù)據(jù)宛畦。
- XML被設(shè)計(jì)為具有自我描述性,通過XML可以發(fā)明自己的標(biāo)簽揍移。
- XML是W3C(World Wide Web Consortium)次和,即萬維網(wǎng)聯(lián)盟的推薦標(biāo)準(zhǔn)。
- XML是沒有任何行為的那伐,僅僅是純文本踏施。
20.2 XML用途
XML 應(yīng)用于 web 開發(fā)的許多方面,常用于簡(jiǎn)化數(shù)據(jù)的存儲(chǔ)和共享罕邀。XML主要用途如下:
(1) XML把數(shù)據(jù)從 HTML 分離
如果你需要在HTML文檔中顯示動(dòng)態(tài)數(shù)據(jù)畅形,那么每當(dāng)數(shù)據(jù)改變時(shí)將花費(fèi)大量的時(shí)間來編輯HTML。通過XML诉探,數(shù)據(jù)能夠存儲(chǔ)在獨(dú)立的XML文件中日熬。這樣你就可以專注于使用 HTML進(jìn)行布局和顯示,并確保修改底層數(shù)據(jù)不再需要對(duì) HTML 進(jìn)行任何的改變肾胯。通過使用幾行 JavaScript碍遍,你就可以讀取一個(gè)外部 XML 文件,然后更新 HTML 中的數(shù)據(jù)內(nèi)容阳液。
(2) XML簡(jiǎn)化數(shù)據(jù)共享
在真實(shí)的世界中怕敬,計(jì)算機(jī)系統(tǒng)和數(shù)據(jù)使用不兼容的格式來存儲(chǔ)數(shù)據(jù)。XML數(shù)據(jù)以純文本格式進(jìn)行存儲(chǔ)帘皿,因此提供了一種獨(dú)立于軟件和硬件的數(shù)據(jù)存儲(chǔ)方法东跪。這讓創(chuàng)建不同應(yīng)用程序可以共享的數(shù)據(jù)變得更加容易。
(3) XML簡(jiǎn)化數(shù)據(jù)傳輸
通過 XML鹰溜,可以在不兼容的系統(tǒng)之間輕松地交換數(shù)據(jù)虽填。對(duì)開發(fā)人員來說,其中一項(xiàng)最費(fèi)時(shí)的挑戰(zhàn)一直是在因特網(wǎng)上的不兼容系統(tǒng)之間交換數(shù)據(jù)曹动。由于可以通過各種不兼容的應(yīng)用程序來讀取數(shù)據(jù)斋日,以XML交換數(shù)據(jù)降低了這種復(fù)雜性。
(4) XML簡(jiǎn)化平臺(tái)的變更
升級(jí)到新的系統(tǒng)(硬件或軟件平臺(tái))墓陈,總是非常費(fèi)時(shí)的恶守。必須轉(zhuǎn)換大量的數(shù)據(jù),不兼容的數(shù)據(jù)經(jīng)常會(huì)丟失贡必。
XML 數(shù)據(jù)以文本格式存儲(chǔ)兔港。這使得 XML 在不損失數(shù)據(jù)的情況下,更容易擴(kuò)展或升級(jí)到新的操作系統(tǒng)仔拟、新應(yīng)用程序或新的瀏覽器衫樊。
(5) XML使您的數(shù)據(jù)更有用
由于XML獨(dú)立于硬件、軟件以及應(yīng)用程序,XML使數(shù)據(jù)更可用科侈,也更有用载佳。不同的應(yīng)用程序都能夠訪問您的數(shù)據(jù),不僅僅在HTML頁(yè)中臀栈,也可以從XML數(shù)據(jù)源中進(jìn)行訪問刚盈。通過XML您的數(shù)據(jù)可供各種閱讀設(shè)備使用(手持的計(jì)算機(jī)、語音設(shè)備挂脑、新聞閱讀器等),還可以供盲人或其他殘障人士使用欲侮。
20.3 XML樹形結(jié)構(gòu)
XML文檔形成了一種樹結(jié)構(gòu)崭闲,它從“根部”開始,然后擴(kuò)展到“枝葉”威蕉。
<?xml version="1.0" encoding="utf-8"?>
<student>
<id>10001</id>
<name>Johnny</name>
<sex>female</sex>
<major>Software engineering</major>
</student>
XML 文檔必須包含根元素刁俭。該元素是所有其他元素的父元素。所有元素均可擁有子元素韧涨。
<?xml version="1.0" encoding="utf-8"?>
<bookstore>
<book category="Cooking">
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="Children">
<title lang="en">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
<book category="Web">
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
</bookstore>
20.4 XML語法
XML 的語法規(guī)則很簡(jiǎn)單牍戚,且很有邏輯。
(1) 所有XML元素都須有關(guān)閉標(biāo)簽
<title lang="en">Everyday Italian</title>
(2) XML 標(biāo)簽對(duì)大小寫敏感
<Message>這是錯(cuò)誤的虑粥。</message>
<message>這是正確的如孝。</message>
(3) XML 必須正確地嵌套
<b><i>This text is bold and italic</b></i> <!--錯(cuò)誤-->
<b><i>This text is bold and italic</i></b> <!--正確-->
(4) XML 文檔必須有根元素
<?xml version="1.0" encoding="utf-8"?>
<root>
<child>
<subchild>.....</subchild>
</child>
</root>
(5) XML 的屬性值必須加引號(hào)
<!--錯(cuò)誤-->
<note date=08/08/2008>
<to>George</to>
<from>John</from>
</note>
<!--正確-->
<note date="08/08/2008">
<to>George</to>
<from>John</from>
</note>
(6) 實(shí)體引用
在 XML 中,一些字符擁有特殊的意義娩贷。如果你把字符 "<" 放在 XML 元素中第晰,會(huì)發(fā)生錯(cuò)誤,因?yàn)榻馕銎鲿?huì)把它當(dāng)作新元素的開始彬祖。
<message>if salary < 1000 then</message> <!--錯(cuò)誤-->
為了避免這個(gè)錯(cuò)誤茁瘦,請(qǐng)用實(shí)體引用來代替 "<" 字符:
<message>if salary < 1000 then</message>
在 XML 中,有 5 個(gè)預(yù)定義的實(shí)體引用(專業(yè)字符):
轉(zhuǎn)義字符 | 代表字符 | 說明 |
---|---|---|
< | < | 小于 |
> | > | 大于 |
& | & | and符 |
' | ' | 單引號(hào) |
" | " | 雙引號(hào) |
(7) XML中的注釋
在XML中編寫注釋的語法與 HTML 的語法很相似储笑。
<!-- 注釋內(nèi)容 -->
(8) 在XML中甜熔,空格會(huì)被保留
HTML會(huì)把多個(gè)連續(xù)的空格字符裁減(合并)為一個(gè),在XML中,文檔中的空格不會(huì)被刪節(jié)突倍。
<message>Hello my name is David.</message>
20.5 XML元素
XML 元素指的是從(且包括)開始標(biāo)簽直到(且包括)結(jié)束標(biāo)簽的部分腔稀。元素可包含其他元素、文本或者兩者的混合物羽历。元素也可以擁有屬性烧颖。
<?xml version="1.0" encoding="utf-8"?>
<bookstore>
<book category="Cooking">
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="Children">
<title lang="en">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
<book category="Web">
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
</bookstore>
在上例中,<bookstore> 和 <book> 都擁有元素內(nèi)容窄陡,因?yàn)樗鼈儼似渌亍?lt;author> 只有文本內(nèi)容炕淮,因?yàn)樗鼉H包含文本。<book> 元素?fù)碛袑傩?(category=" Children ")跳夭。
XML命名規(guī)則
- 名稱可以含字母涂圆、數(shù)字以及其他的字符
- 名稱不能以數(shù)字或者標(biāo)點(diǎn)符號(hào)開始
- 名稱不能以字符“xml”(或者 XML们镜、Xml)開始
- 名稱不能包含空格
- 可使用任何名稱,沒有保留的字詞润歉。
20.6 XML屬性
XML元素可以在開始標(biāo)簽中包含屬性模狭,類似HTML。屬性 (Attribute) 提供關(guān)于元素的額外(附加)信息踩衩。
<?xml version="1.0" encoding="utf-8"?>
<bookstore>
<book category="Cooking">
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="Children">
<title lang="en">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
<book category="Web">
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
</bookstore>
20.7 XML驗(yàn)證
XML Schema是W3C支持的基于XML的驗(yàn)證方式嚼鹉,它名為XML Schema。
<?xml version="1.0" encoding="utf-8"?>
<xs:element name="note">
<xs:complexType>
<xs:sequence>
<xs:element name="to" type="xs:string"/>
<xs:element name="from" type="xs:string"/>
<xs:element name="heading" type="xs:string"/>
<xs:element name="body" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
第二十一章 JSON
21.1 JSON簡(jiǎn)介
盡管有許多宣傳關(guān)于 XML 如何擁有跨平臺(tái)驱富,跨語言的優(yōu)勢(shì)锚赤,然而,除非應(yīng)用于Web Services褐鸥,否則线脚,在普通的 Web 應(yīng)用中,開發(fā)者經(jīng)常為 XML 的解析傷透了腦筋叫榕,無論是服務(wù)器端生成或處理 XML浑侥,還是客戶端用JavaScript解析XML,都常常導(dǎo)致復(fù)雜的代碼晰绎,極低的開發(fā)效率寓落。實(shí)際上,對(duì)于大多數(shù)Web應(yīng)用來說荞下,他們根本不需要復(fù)雜的XML來傳輸數(shù)據(jù)零如,XML 的擴(kuò)展性很少具有優(yōu)勢(shì),許多AJAX應(yīng)用甚至直接返回HTML片段來構(gòu)建動(dòng)態(tài) Web 頁(yè)面锄弱。和返回XML并解析它相比考蕾,返回HTML片段大大降低了系統(tǒng)的復(fù)雜性,但同時(shí)缺少了一定的靈活性会宪。
現(xiàn)在肖卧,JSON為Web應(yīng)用開發(fā)者提供了另一種數(shù)據(jù)交換格式。JSON即JavaScript Object Natation掸鹅,它是一種輕量級(jí)的數(shù)據(jù)交換格式塞帐,非常適合于服務(wù)器與JavaScript的交互。
21.2 JSON語法
和XML一樣巍沙,JSON也是基于純文本的數(shù)據(jù)格式葵姥。由于JSON天生是為JavaScript準(zhǔn)備的,因此句携,JSON的數(shù)據(jù)格式非常簡(jiǎn)單榔幸,您可以用JSON傳輸一個(gè)簡(jiǎn)單的String,Number,Boolean也可以傳輸一個(gè)數(shù)組削咆,或者一個(gè)復(fù)雜的 Object 對(duì)象牍疏。
JSON語法是JavaScript對(duì)象表示法語法的子集。
- 數(shù)據(jù)在名稱/值對(duì)中(鍵值對(duì))拨齐;
- 數(shù)據(jù)由逗號(hào)分隔鳞陨;
- 花括號(hào)保存對(duì)象;
- 方括號(hào)保存數(shù)組瞻惋。
(1) JSON名稱/值對(duì)(鍵值對(duì))
JSON數(shù)據(jù)的書寫格式是:名稱/值的鍵值對(duì)對(duì)厦滤。鍵值對(duì)對(duì)包括字段名稱(在雙引號(hào)中),后面寫一個(gè)冒號(hào)歼狼,然后是值掏导。
"name": "Johnny"
(2) JSON值
JSON值可以是:
- 數(shù)字(整數(shù)或浮點(diǎn)數(shù))
- 字符串(在雙引號(hào)中)
- 邏輯值(true 或 false)
- 數(shù)組(在方括號(hào)中)
- 對(duì)象(在花括號(hào)中)
- null
(3) JSON對(duì)象
JSON對(duì)象在花括號(hào)中書寫,對(duì)象可以包含多個(gè)名稱/值對(duì)蹂匹。
{
"id": 10001,
"name": "Johnny",
"sex": "female",
"major": "Software engineering"
}
(4) JSON數(shù)組
JSON 數(shù)組在方括號(hào)中書寫,數(shù)組可包含多個(gè)對(duì)象凹蜈。
{
"employees": [
{
"firstName":"John",
"lastName":"Doe"
},
{
"firstName":"Anna",
"lastName":"Smith"
},
{
"firstName":"Peter",
"lastName":"Jones"
}
]
}
(5) JSON使用JavaScript語法
因?yàn)镴SON使用JavaScript語法限寞,所以無需額外的軟件就能處理 JavaScript 中的 JSON。通過 JavaScript仰坦,您可以創(chuàng)建一個(gè)對(duì)象數(shù)組履植,并像這樣進(jìn)行賦值。
{
"employees": [
{
"firstName":"John",
"lastName":"Doe"
},
{
"firstName":"Anna",
"lastName":"Smith"
},
{
"firstName":"Peter",
"lastName":"Jones"
}
]
}
可以像這樣訪問JavaScript對(duì)象數(shù)組中的第一項(xiàng):
employees[0].lastName;
可以像這樣修改數(shù)據(jù):
employees[0].lastName = "Jobs";
(6) JSON文件
JSON文件的文件類型是 ".json"
JSON文本的MIME類型是 "application/json"
21.3 JSON使用
JSON最常見的用法之一悄晃,是從web服務(wù)器上讀取JSON數(shù)據(jù)(作為文件或作為 HttpRequest)玫霎,將JSON數(shù)據(jù)轉(zhuǎn)換為JavaScript對(duì)象,然后在網(wǎng)頁(yè)中使用該數(shù)據(jù)妈橄。
(1) 將json字符串解析為json對(duì)象
<script>
var res = "{\"id\": 10001,\"name\": \"Johnny\",\"sex\": \"female\",\"major\": \"Software engineering\"}";
var obj = JSON.parse(res);//將json字符串解析為json對(duì)象
alert(obj.name);
</script>
(2) 將json對(duì)象轉(zhuǎn)為json字符串
<script>
var obj = {
id: 10001,
name: "Johnny",
sex: "female",
major: "Software engineering"
};
var str = JSON.stringify(obj); //將json對(duì)象轉(zhuǎn)為json字符串
alert(str);
</script>
第二十二章 Ajax
Ajax庶近,是Asynchronous JavaScript + XML的簡(jiǎn)寫。這種技術(shù)能夠向服務(wù)器請(qǐng)求額外的數(shù)據(jù)而無刷新頁(yè)面眷蚓,會(huì)帶來更好的用戶體驗(yàn)鼻种。Ajax技術(shù)核心是XMLHttpRequest對(duì)象(簡(jiǎn)稱XHR),這是由微軟首先引入的一個(gè)特性沙热,其他瀏覽器提供商后來都提供了相同的實(shí)現(xiàn)叉钥。
在實(shí)際項(xiàng)目中,Ajax的實(shí)現(xiàn)是由jQuery來實(shí)現(xiàn)的篙贸,請(qǐng)參照jQuery課程投队。