結(jié)合函數(shù)fn分析:var聲明變量和直接用標(biāo)識符初始化的細(xì)節(jié)
1.var聲明會指定變量的作用域,即用 var 操作符定義的變量將成為定義該變量的作用域中的局部變量
--fn執(zhí)行完畢,在全局中訪問c會報錯說變量未定義,說明c的作用域只是在fn函數(shù)里面,而直接使用d = 4聲明初始化的變量則
默認(rèn)是全局作用域,從c的輸出可以驗證
2.直接標(biāo)識符初始化變量則默認(rèn)是widow的一個屬性,在全局中可以訪問,
--《JavaScript面向?qū)ο缶幊讨改稀?第二版)中提到直接標(biāo)識符初始化的變量是window的一個屬性,這可以在window.b輸出
為2得到印證。瀏覽器在訪問window對象的屬性和方法可以省略‘window.’,也就是說在代碼執(zhí)行時候遇到?jīng)]有var聲明的標(biāo)示符
會默認(rèn)把它當(dāng)成window的屬性
--如此說來,b = 2,這句代碼其實是為window對象聲明一個屬性并初始化, var 聲明的變量不是window的屬性window.a輸
出undefiend是因為在訪問window.a的時候,由于在window對象及其原型鏈中沒有搜索到標(biāo)示符為a的屬性,所以就為window
聲明了a屬性,但是并沒有初始化,有聲明沒初始化的變量被默認(rèn)賦值為undefined,這就是a的值為undefined而不引起瀏覽器
報錯
--發(fā)現(xiàn)《JavaScript高級程序設(shè)計》(第三版)中提到的‘所有在全局作用域中聲明的變量,函數(shù)都會成為window對象的屬性
和方法’這句話不太正確,window屬性必須通過window.obj或者不使用var直接obj = {}方式定義的變量才會是window的屬
性;在全局作用域中使用var聲明的變量不是window的屬性,比如以下的a;
--全局變量的定義可以通過b = 1,window.a的方式定義,局部變量通過var定義,var其實能夠定義全局變量只是需要在全局環(huán)
境中定義,個人覺得它本質(zhì)上還是局部變量,只不過是var在指定變量的作用域時候,這個作用域剛好是全局作用域,作用域存在
它就不會被釋放,而全局作用域又是依賴全局執(zhí)行環(huán)境存在,全局執(zhí)行環(huán)境只有在頁面關(guān)閉時候才會退出,使得它能夠在頁面的每
個地方訪問到。
var a = 1;
b = 2;
function fn(){
var c = 3;
d = 4;
}
fn();
console.log(a); // 1
console.log(c); // Uncaught ReferenceError: c is not defined
console.log(d); // 4
console.log(window.a); // undefined
console.log(window.b); // 2
3.筆者遺留的問題,既然b是window的屬性,那么它?在棧中沒有分配存儲空間而var聲明的在棧中分配了空間?(至今苦于沒有學(xué)習(xí)到JavaScript中能夠獲取內(nèi)存信息的方法所以一直沒有驗證,希望能解決的朋友能夠告訴我一聲)。
4.以下是結(jié)合以上結(jié)論個人對 x,window.x,var x 的理解:
1.var 關(guān)鍵字其實是用來為變量申請內(nèi)存的,瀏覽器在解析遇到var關(guān)鍵字時候會為它聲明的變量在棧中分配存儲空間,那么遇
到 b = 1; 這類不帶var表達(dá)式時會認(rèn)為b已經(jīng)分配內(nèi)存了,所以并沒有為它分配內(nèi)存;
2.瀏覽器執(zhí)行行流到達(dá) b = 1;時,語句才真正被執(zhí)行賦值操作,然而我們知道js代碼執(zhí)行中如果曾經(jīng)沒有被var聲明過,它會
當(dāng)成window的一個屬性,然而window是一個對象,window標(biāo)識符的值是一個地址存在棧中指向堆內(nèi)存中一個對象,堆內(nèi)存又
是動態(tài)分配的,b = 1;對還沒分配內(nèi)存的變量b賦值會為它在堆中分配內(nèi)存(瀏覽器解析時候已經(jīng)將需要分棧內(nèi)存的變量分配好
內(nèi)存,執(zhí)行時候除了執(zhí)行環(huán)境變化才會操作棧內(nèi)存,這也是為什么棧中保存的數(shù)據(jù)是固定大小的),而f;是不會分配內(nèi)存的。所
以f沒被映射到內(nèi)存中。
--以下輸出語句是實現(xiàn)獲取f的值在打印在控制臺的功能,計算機(jī)無法通過b對應(yīng)的地址取到值所以報錯,然而對比一下第二句代
碼console.log(window.f);輸出undefined,然而不是說瀏覽器遇到?jīng)]有var聲明的f會當(dāng)成瀏覽器屬性嗎?是的這并不矛
盾,f和window.f還是不一樣的,window.f執(zhí)行過程:a).在window對象中獲取f的值,如果沒有找到執(zhí)行下一個過程;b).設(shè)
置f的值,沒有指定值,默認(rèn)賦值為undefined,而f;語句并不會調(diào)用設(shè)值方法,所以錯誤了
3.總結(jié):變量和對象有沒有定義是指它是否被分配內(nèi)存,js中 var和賦值操作發(fā)生時候,如果操作的變量事先沒有定義過,那
么將會為該變量分配內(nèi)存空間;
?// f標(biāo)識符是沒有被聲明過,也不存在window對象中
console.log(f); // 報錯:f未定義,
console.log(window.f); // undefined
最后編輯于 :2017.12.04 23:14:05
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者 【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。 平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。