JavaScript 變量、作用域和內(nèi)存問(wèn)題

基本類型和引用類型的值


基本類型值指的是簡(jiǎn)單的數(shù)據(jù)段,而引用類型值指的是那些可能由多個(gè)值構(gòu)成的對(duì)象祭陷。
javascript不允許直接訪問(wèn)內(nèi)存中的位置,也就是說(shuō)不能直接操作對(duì)象的內(nèi)存空間趣席。

在很多語(yǔ)言中兵志,字符串以對(duì)象的形式表示,因此被認(rèn)為是引用類型的宣肚。ECAMScript放棄了這一傳統(tǒng)想罕。

動(dòng)態(tài)的屬性

對(duì)于引用類型的值,我們可以添加霉涨、改變和刪除其屬性和方法按价。

復(fù)制變量值

從一個(gè)變量向另一個(gè)變量復(fù)制基本類型的值惭适,會(huì)在變量對(duì)象上創(chuàng)建一個(gè)新值,然后把該值復(fù)制到為新變量分配的位置上俘枫。

var num1  =5;
var num2 =num1;

num1和num2中的5是完全獨(dú)立的腥沽,num2中的5只是num1中5的一個(gè)副本。

從一個(gè)變量向另一個(gè)變量復(fù)制引用類型的值鸠蚪,同樣也會(huì)將存儲(chǔ)在變量對(duì)象中的值復(fù)制一份放到新變量分配的空間中今阳。不同的是,這個(gè)值的副本實(shí)際上是一個(gè)指針茅信。

var obj1 = new Object();
var obj2 = obj1;
obj1.name = 'asdf';
alert(obj2.name); //asdf

傳遞參數(shù)

ECMAScript中所有函數(shù)的參數(shù)都是按值傳遞的盾舌。

function addTen (num) {
    num +=10;
    return num;
}
var count = 20;
var result = addTen(count);
alert(count); //20,沒(méi)有變化
function setName(obj) {
    obj.name = 'asdf';
}
var person = new Object();
setName(person);
alert(person.name); //asdf

很多人錯(cuò)誤的認(rèn)為:在局部作用域中修改的對(duì)象會(huì)在全局作用域中反映出來(lái),就說(shuō)明參數(shù)是按引用傳遞的蘸鲸⊙矗看下面的例子:

function setName(obj) {
    obj.name = 'asdf';
    obj = new Object();
    obj.name = 'qwer';
}

var person = new Object();
setName(person);
alert(person.name); //asdf

檢測(cè)類型

typeof操作符用來(lái)檢測(cè)變量是不是基本類型。
instanceof操作符用來(lái)檢測(cè)引用類型酌摇。

alert(person instanceof Objcet);

使用typeof操作符檢測(cè)函數(shù)是膝舅,會(huì)返回function。在Safari 5及之前版本和Chrome7之前版本中使用typeof檢測(cè)正則表達(dá)式時(shí)窑多,由于規(guī)范的原因仍稀,這個(gè)操作符也會(huì)返回function。ECMA-262規(guī)定任何內(nèi)部實(shí)現(xiàn)[[call]]方法的對(duì)象都應(yīng)該在應(yīng)用typeof操作符時(shí)返回function埂息。在IE和Firefox中技潘,對(duì)正則表達(dá)式應(yīng)用typeof時(shí)會(huì)返回Object。

執(zhí)行環(huán)境及作用域


執(zhí)行環(huán)境(execution context)定義了變量或函數(shù)有權(quán)訪問(wèn)的其他數(shù)據(jù)千康,決定了它們各自的行為享幽。每個(gè)執(zhí)行環(huán)境都有一個(gè)與之關(guān)聯(lián)的變量對(duì)象(variable object),環(huán)境中定義的所有變量和函數(shù)都保存在這個(gè)對(duì)象中拾弃。雖然我們編寫的代碼訪問(wèn)不到值桩,但解析器在處理數(shù)據(jù)時(shí)會(huì)在后臺(tái)使用它。

全局執(zhí)行環(huán)境是最外圍的一個(gè)執(zhí)行環(huán)境豪椿。根據(jù)ECMAScript實(shí)現(xiàn)所在宿主環(huán)境不同颠毙,表示執(zhí)行環(huán)境的對(duì)象也不一樣。在Web瀏覽器中砂碉,全局執(zhí)行環(huán)境被認(rèn)為是window對(duì)象蛀蜜,因此所有全局變量和函數(shù)都是作為window對(duì)象的屬性和方法創(chuàng)建的。某個(gè)執(zhí)行環(huán)境中的所有代碼執(zhí)行完畢后增蹭,該環(huán)境被銷毀滴某,保存在其中的所有變量和函數(shù)定義也隨之銷毀(全局執(zhí)行環(huán)境直到應(yīng)用程序退出--例如關(guān)閉網(wǎng)頁(yè)或?yàn)g覽器--時(shí)才會(huì)被銷毀)。

每個(gè)函數(shù)都有自己的執(zhí)行環(huán)境。

當(dāng)代碼在一個(gè)環(huán)境中執(zhí)行時(shí)霎奢,會(huì)創(chuàng)建變量對(duì)象的一個(gè)作用域鏈(scope chain)户誓。作用域鏈的用途是保證對(duì)執(zhí)行環(huán)境有權(quán)訪問(wèn)的所有變量和函數(shù)的有序訪問(wèn)。作用域鏈的前端幕侠,始終都是當(dāng)前執(zhí)行的代碼所在環(huán)境的變量對(duì)象帝美。如果這個(gè)環(huán)境是函數(shù),則將其活動(dòng)對(duì)象(activation object)作為變量對(duì)象晤硕〉刻叮活動(dòng)對(duì)象在最開始時(shí)只包含一個(gè)變量,即arguments對(duì)象(這個(gè)對(duì)象在全局環(huán)境中是不存在的)舞箍。全局執(zhí)行環(huán)境的變量對(duì)象始終都是作用域鏈中的最后一個(gè)對(duì)象舰褪。

延長(zhǎng)作用域鏈

雖然執(zhí)行環(huán)境只有兩種:全局和局部(函數(shù)),但還有其他辦法來(lái)延長(zhǎng)作用域鏈疏橄。因?yàn)橛行┱Z(yǔ)句可以在作用域鏈的前端臨時(shí)增加一個(gè)變量對(duì)象占拍,該變量對(duì)象會(huì)在代碼執(zhí)行后被移除。具體來(lái)說(shuō)捎迫,就是當(dāng)執(zhí)行流進(jìn)入下列任何一個(gè)語(yǔ)句時(shí)晃酒,作用域鏈就會(huì)得到加長(zhǎng):

  • try-catch語(yǔ)句的catch塊
  • with語(yǔ)句

對(duì)于with語(yǔ)句來(lái)說(shuō),會(huì)將指定的對(duì)象添加到作用域鏈中窄绒。對(duì)catch語(yǔ)句來(lái)說(shuō)贝次,會(huì)創(chuàng)建一個(gè)新的變量對(duì)象,其中包含的是被拋出的錯(cuò)誤對(duì)象的聲明颗祝。

function buildUrl () {
    var qs = "?debug=true";

    with (location) {
        var url = href + qs;
    }
    return url;
}

在IE8及之前版本的JavaScript實(shí)現(xiàn)中,存在一個(gè)與標(biāo)準(zhǔn)不一致的地方恼布,即catch語(yǔ)句中捕獲的錯(cuò)誤對(duì)象會(huì)被添加到執(zhí)行環(huán)境的變量對(duì)象螺戳,而不是catch語(yǔ)句的變量對(duì)象中。換句話折汞,即使是在catch塊的外部也可以訪問(wèn)到錯(cuò)誤對(duì)象倔幼。IE9修復(fù)了這個(gè)問(wèn)題。

沒(méi)有塊級(jí)作用域

聲明變量
使用var聲明的變量會(huì)自動(dòng)被添加到最接近的環(huán)境中爽待。在函數(shù)內(nèi)部损同,最接近的環(huán)境就是函數(shù)的局部環(huán)境。如果初始化變量時(shí)沒(méi)有使用var聲明鸟款,該變量會(huì)自動(dòng)添加到全局環(huán)境膏燃。

在嚴(yán)格模式下,初始化未經(jīng)聲明的變量會(huì)導(dǎo)致錯(cuò)誤何什。

查詢標(biāo)識(shí)符

垃圾收集


JavaScript具有自動(dòng)垃圾回收機(jī)制组哩,執(zhí)行環(huán)境會(huì)負(fù)責(zé)管理代碼執(zhí)行過(guò)程中使用的內(nèi)存。
垃圾收集器必須跟蹤哪個(gè)變量有用哪個(gè)變量沒(méi)用,對(duì)于不在有用的變量打上標(biāo)記伶贰,以備將來(lái)收回其占用的內(nèi)存蛛砰。用于標(biāo)識(shí)無(wú)用變量的策略可能會(huì)因?qū)崿F(xiàn)而異,但具體到瀏覽器中的實(shí)現(xiàn)黍衙,則通常有兩個(gè)策略泥畅。

標(biāo)記清除

JavaScript中常用的垃圾收集方式是標(biāo)記清除(mark-and-sweep)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末琅翻,一起剝皮案震驚了整個(gè)濱河市位仁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌望迎,老刑警劉巖障癌,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異辩尊,居然都是意外死亡涛浙,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門摄欲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)轿亮,“玉大人,你說(shuō)我怎么就攤上這事胸墙∥易ⅲ” “怎么了?”我有些...
    開封第一講書人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵迟隅,是天一觀的道長(zhǎng)但骨。 經(jīng)常有香客問(wèn)我,道長(zhǎng)奔缠,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任吼野,我火速辦了婚禮校哎,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘瞳步。我一直安慰自己闷哆,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開白布单起。 她就那樣靜靜地躺著抱怔,像睡著了一般。 火紅的嫁衣襯著肌膚如雪嘀倒。 梳的紋絲不亂的頭發(fā)上野蝇,一...
    開封第一講書人閱讀 49,764評(píng)論 1 290
  • 那天讼稚,我揣著相機(jī)與錄音,去河邊找鬼绕沈。 笑死锐想,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的乍狐。 我是一名探鬼主播赠摇,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼浅蚪!你這毒婦竟也來(lái)了藕帜?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤惜傲,失蹤者是張志新(化名)和其女友劉穎洽故,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體盗誊,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡时甚,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了哈踱。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片荒适。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖开镣,靈堂內(nèi)的尸體忽然破棺而出刀诬,到底是詐尸還是另有隱情,我是刑警寧澤邪财,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布陕壹,位于F島的核電站,受9級(jí)特大地震影響树埠,放射性物質(zhì)發(fā)生泄漏糠馆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一弥奸、第九天 我趴在偏房一處隱蔽的房頂上張望榨惠。 院中可真熱鬧奋早,春花似錦盛霎、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至掉奄,卻和暖如春规个,著一層夾襖步出監(jiān)牢的瞬間凤薛,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工诞仓, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留缤苫,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓墅拭,卻偏偏與公主長(zhǎng)得像活玲,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子谍婉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容