[TOC]
標(biāo)識(shí)符
在開(kāi)始講解 JavaScript 中的變量聲明前,我們先來(lái)了解一下什么是標(biāo)識(shí)符,它是指變量、函數(shù)、屬性的名稱,或者函數(shù)的參數(shù)名,<u>在 JavaScript 中所有的一切都是大小寫敏感的,標(biāo)識(shí)符不能是關(guān)鍵字、保留字、true、false和null</u>,所以firstName不等于FirstName,而且用True聲明一個(gè)變量是允許的。
變量
<u>Javascript定義的變量是松散型的,可以用來(lái)保存任何類型的數(shù)據(jù)。</u>允許在定義變量時(shí)同時(shí)設(shè)置變量的值。在這里使用var關(guān)鍵字定義了一個(gè)名為myName的變量,它是一個(gè)字符串值xiaoming。
var myName = 'xiaoming';
由于變量是松散型的,那么,<u>在變量的生命周期結(jié)束前是可以進(jìn)行重新賦值的。</u>
var myName = 'xiaoming';
myName = 20;
在函數(shù)中定義的變量稱為局部變量,一般情況下,<u>局部變量會(huì)在函數(shù)退出后被銷毀??梢栽诤瘮?shù)外部任何地方訪問(wèn)到,我們稱之為全局變量。</u>
function todo() {
var myName = 'xiaoming';
}
var age = 20;
todo();
console.log(myName); // ReferenceError: myName is not defined
console.log(age ); // 20
<u>一條語(yǔ)句可以同時(shí)聲明多個(gè)變量。</u>
var myName = 'xiaoming', age = 20, sleep = false;
作用域
我們?cè)賮?lái)看這個(gè)例子,當(dāng)我們console.log(myName)時(shí)打印了xiaoming,程序到底都做了些什么事情,它是怎么知道我們要訪問(wèn)的內(nèi)容并如期地顯示給我們看的?
var myName = 'xiaoming';
console.log(myName);
變量的作用域意思是變量在哪里起作用,保證能在其生命周期中被訪問(wèn)到。
函數(shù)執(zhí)行環(huán)境
<u>在函數(shù)內(nèi)執(zhí)行代碼前,都會(huì)創(chuàng)建一個(gè)函數(shù)的執(zhí)行環(huán)境,在這個(gè)執(zhí)行環(huán)境中存在一個(gè)變量對(duì)象,所有定義的變量和函數(shù)都會(huì)保存在這個(gè)對(duì)象上。</u>它是一個(gè)抽象的概念,我們是無(wú)法直接訪問(wèn)的,JavaScript 解析器會(huì)在后臺(tái)幫助我們處理變量和數(shù)據(jù)之間的關(guān)系。當(dāng)執(zhí)行環(huán)境被銷毀,作用域也就不復(fù)存在了。
全局執(zhí)行環(huán)境
Javascript中一切皆對(duì)象,在瀏覽器中,全局執(zhí)行環(huán)境就是Window對(duì)象,所有在程序中定義的變量與函數(shù)都是掛載在Window對(duì)象的屬性和方法。<u>該執(zhí)行環(huán)境會(huì)在腳本結(jié)束后被銷毀(離開(kāi)頁(yè)面或關(guān)閉標(biāo)簽頁(yè)),定義在其中的變量和函數(shù)也會(huì)隨之銷毀。</u>
Arguments 對(duì)象
在每個(gè)函數(shù)中執(zhí)行代碼時(shí),會(huì)創(chuàng)建自己的執(zhí)行環(huán)境。在該執(zhí)行環(huán)境中會(huì)創(chuàng)建一個(gè)arguments對(duì)象保存所有傳遞給該函數(shù)的參數(shù),它是一個(gè)類數(shù)組,所以也可以通過(guò)[]訪問(wèn)指定索引上保存的值,通過(guò).length訪問(wèn)數(shù)組的長(zhǎng)度。Arguments對(duì)象連同定義的變量和函數(shù)會(huì)被保存在變量對(duì)象上。
作用域鏈
1.作用域鏈?zhǔn)潜WC變量及函數(shù)的有序訪問(wèn)的關(guān)鍵。<u>在解析標(biāo)識(shí)符時(shí),通過(guò)作用域鏈向上追溯逐步搜索,直到找到所對(duì)應(yīng)的數(shù)據(jù)。</u>
function todo(msg) {
function say() {
console.log(msg);
}
say();
}
todo('hi');
在這個(gè)例子里,先是定義了一個(gè)todo函數(shù),并且定義了參數(shù)msg。在執(zhí)行了todo('hi');時(shí),會(huì)創(chuàng)建一個(gè)todo的執(zhí)行環(huán)境,msg意味著是傳入的字符串hi,并保存在了arguments對(duì)象里。緊接著在todo作用域中定義了say函數(shù)并執(zhí)行say函數(shù),會(huì)為say創(chuàng)建一個(gè)執(zhí)行環(huán)境,在say執(zhí)行環(huán)境中訪問(wèn)了msg這個(gè)標(biāo)識(shí)符,在當(dāng)前執(zhí)行環(huán)境中未找到該變量,會(huì)向外部todo環(huán)境中尋找,在找到了msg變量后并打印了'hi'。
2.<u>最外層的作用域是window對(duì)象,如果在解析的過(guò)程中沒(méi)找到合適的數(shù)據(jù)會(huì)在該作用域中自動(dòng)創(chuàng)建。</u>
function todo() {
myName = 'xiaoming';
}
todo();
console.log(myName); // 'xiaoming'