JS中的變量對(duì)象

函數(shù)參數(shù)傳遞的過(guò)程實(shí)際上就是實(shí)參像形參復(fù)制值的過(guò)程穗慕。

  • 在向參數(shù)傳遞基本類型的值時(shí),被傳遞(實(shí)參)的值會(huì)復(fù)制給一個(gè)局部變量(形參),形參值的變化不會(huì)對(duì)函數(shù)外的實(shí)參產(chǎn)生影響忠蝗。
  • 在向參數(shù)傳遞引用類型的值時(shí),會(huì)把這個(gè)值在內(nèi)存中的地址復(fù)制給形參滨溉。這時(shí)這個(gè)形參也指向了函數(shù)外的實(shí)參什湘,因此這個(gè)形參的變化也會(huì)導(dǎo)致實(shí)參的變化。
  function addTen(num) {
    num += 10;
    return num;
  }

  var count = 20, result = addTen(count);
  alert(count); //20

這里函數(shù) addTen()的參數(shù)num晦攒,實(shí)際上是函數(shù)的局部變量闽撤。在調(diào)用函數(shù)時(shí),變量count作為參數(shù)傳遞給函數(shù)脯颜。由于 count 的值是20哟旗,所以數(shù)值20被復(fù)制給參數(shù)num。在函數(shù)內(nèi)部栋操,這個(gè)參數(shù)被加了10闸餐,但這并不會(huì)影響函數(shù)外部的count變量。

當(dāng)向參數(shù)傳遞的值為對(duì)象時(shí)矾芙,例如:

 function setName(obj) {
    obj.name = "Nicholas";
  }

  var person = new Object();
  person.name = "Greg";
  setName(person);
  alert(person.name);  //"Nicholas"

這里首先是創(chuàng)建了一個(gè)對(duì)象舍沙,保存在變量person中,并且給變量的 name屬性賦值為 "Greg"剔宪。然后這個(gè)變量被當(dāng)作參數(shù)傳遞給函數(shù)setName的參數(shù) obj拂铡。在函數(shù)內(nèi)部壹无,objperson 指向同一個(gè)對(duì)象,因?yàn)閭鬟f的是對(duì)象的地址感帅。所以給objname屬性賦值后斗锭,也會(huì)改變 personname屬性值。

如果在函數(shù)內(nèi)部為obj新建一個(gè)對(duì)象實(shí)例失球,這個(gè)新對(duì)象實(shí)例會(huì)開辟新的內(nèi)存空間岖是,導(dǎo)致 obj的地址和person不同。此時(shí)实苞,objperson 將指向兩個(gè)不同的對(duì)象豺撑,所以互不影響。例如:

  function setName(obj) {
    obj.name = "Nicholas"; // 這個(gè)obj和person指向的地址相同硬梁,即函數(shù)外person創(chuàng)建的對(duì)象前硫。    
    obj = new Object(); // 新建實(shí)例對(duì)象,導(dǎo)致obj指向另一個(gè)地址    
    obj.name = "Greg";
  }

  var person = new Object();
  person.name = "Jhon";
  setName(person);
  alert(person.name); //"Nicholas"

全局上下文中的變量對(duì)象

全局對(duì)象(Global object) 是在進(jìn)入任何執(zhí)行上下文之前就已經(jīng)創(chuàng)建了的對(duì)象荧止;這個(gè)對(duì)象只存在一份屹电,它的屬性在程序中任何地方都可以訪問(wèn),全局對(duì)象的生命周期終止于程序退出那一刻跃巡。

全局對(duì)象初始創(chuàng)建階段將Math危号、StringDate素邪、parseInt 作為自身屬性外莲,等屬性初始化,同樣也可以有額外創(chuàng)建的其它對(duì)象作為屬性(其可以指向到全局對(duì)象自身)兔朦。例如偷线,在DOM中,全局對(duì)象的window屬性就可以引用全局對(duì)象自身(當(dāng)然沽甥,并不是所有的具體實(shí)現(xiàn)都是這樣):

global = {
  Math: <...>,
  String: <...>
  ...
  ...
  window: global //引用自身
};

函數(shù)上下文中的變量對(duì)象

在函數(shù)執(zhí)行上下文中声邦,變量對(duì)象(VO)是不能直接訪問(wèn)的,此時(shí)由活動(dòng)對(duì)象(activation object,縮寫為AO)扮演 VO 的角色摆舟。

活動(dòng)對(duì)象是在進(jìn)入函數(shù)上下文時(shí)刻被創(chuàng)建的亥曹,它通過(guò)函數(shù)的arguments屬性初始化。arguments屬性的值是 Arguments對(duì)象:

Arguments 對(duì)象是活動(dòng)對(duì)象的一個(gè)屬性恨诱,它包括如下屬性:

  • callee :指向當(dāng)前函數(shù)的引用媳瞪;
  • length : 真正傳遞的參數(shù)個(gè)數(shù);
  • properties-indexes (字符串類型的整數(shù)): 屬性的值就是函數(shù)的參數(shù)值(按參數(shù)列表從左到右排列)照宝。 properties-indexes 內(nèi)部元素的個(gè)數(shù)等于arguments.length蛇受,properties-indexes的值和實(shí)際傳遞進(jìn)來(lái)的參數(shù)之間是共享的。
function foo(x, y, z) {
 
  // 聲明的函數(shù)參數(shù)數(shù)量arguments (x, y, z)
  alert(foo.length); // 3
 
  // 真正傳進(jìn)來(lái)的參數(shù)個(gè)數(shù)(only x, y)
  alert(arguments.length); // 2
 
  // 參數(shù)的callee是函數(shù)自身
  alert(arguments.callee === foo); // true
 
  // 參數(shù)共享
 
  alert(x === arguments[0]); // true
  alert(x); // 10
 
  arguments[0] = 20;
  alert(x); // 20
 
  x = 30;
  alert(arguments[0]); // 30
 
  // 不過(guò)厕鹃,沒(méi)有傳進(jìn)來(lái)的參數(shù)z龙巨,和參數(shù)的第3個(gè)索引值是不共享的

  z = 40;
  alert(arguments[2]); // undefined
 
  arguments[2] = 50;
  alert(z); // 40
 
}
 
foo(10, 20);

現(xiàn)在在嚴(yán)格模式下笼呆,arguments 對(duì)象已與過(guò)往不同熊响。arguments 不再與函數(shù)的實(shí)際形參之間共享旨别,同時(shí)caller屬性也被移除。

剩余參數(shù)汗茄、默認(rèn)參數(shù)和解構(gòu)賦值參數(shù)

在嚴(yán)格模式下秸弛,剩余參數(shù)、默認(rèn)參數(shù)和解構(gòu)賦值參數(shù)的存在不會(huì)改變 arguments對(duì)象的行為洪碳,但是在非嚴(yán)格模式下就有所不同了递览。

當(dāng)非嚴(yán)格模式中的函數(shù)沒(méi)有包含剩余參數(shù)、默認(rèn)參數(shù)和解構(gòu)賦值瞳腌,那么arguments對(duì)象中的值會(huì)跟蹤參數(shù)的值(反之亦然)绞铃。看下面的代碼:

function func(a) { 
  arguments[0] = 99;   // 更新了arguments[0] 同樣更新了a
  console.log(a);
}
func(10); // 99

并且

function func(a) { 
  a = 99;              // 更新了a 同樣更新了arguments[0] 
  console.log(arguments[0]);
}
func(10); // 99

當(dāng)非嚴(yán)格模式中的函數(shù)有包含剩余參數(shù)嫂侍、默認(rèn)參數(shù)和解構(gòu)賦值儿捧,那么arguments對(duì)象中的值不會(huì)跟蹤參數(shù)的值(反之亦然)√舫瑁看下面的代碼:

function func(a = 55) { 
  a = 99; // updating a does not also update arguments[0]
  console.log(arguments[0]);
}
func(10); // 10

并且

function func(a = 55) { 
  console.log(arguments[0]);
}
func(); // undefined
delete

關(guān)于變量菲盾,還有一個(gè)重要的知識(shí)點(diǎn)。變量相對(duì)于簡(jiǎn)單屬性來(lái)說(shuō)各淀,變量有一個(gè)特性(attribute):{ DontDelete },這個(gè)特性的含義就是不能用 delete 操作符直接刪除變量屬性懒鉴。

a = 10;
alert(window.a); // 10
 
alert(delete a); // true
 
alert(window.a); // undefined
 
var b = 20;
alert(window.b); // 20
 
alert(delete b); // false
 
alert(window.b); // still 20

但是這個(gè)規(guī)則在有個(gè)上下文里不起走樣,那就是eval上下文碎浇,變量沒(méi)有 { DontDelete } 特性临谱。

eval('var a = 10;');
alert(window.a); // 10
 
alert(delete a); // true
 
alert(window.a); // undefined

參考文章

Arguments 對(duì)象
深入理解JavaScript系列(12):變量對(duì)象(Variable Object)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市奴璃,隨后出現(xiàn)的幾起案子悉默,更是在濱河造成了極大的恐慌,老刑警劉巖溺健,帶你破解...
    沈念sama閱讀 218,607評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件麦牺,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡鞭缭,警方通過(guò)查閱死者的電腦和手機(jī)剖膳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,239評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)岭辣,“玉大人吱晒,你說(shuō)我怎么就攤上這事÷偻” “怎么了仑濒?”我有些...
    開封第一講書人閱讀 164,960評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵叹话,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我墩瞳,道長(zhǎng)驼壶,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,750評(píng)論 1 294
  • 正文 為了忘掉前任喉酌,我火速辦了婚禮热凹,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘泪电。我一直安慰自己般妙,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,764評(píng)論 6 392
  • 文/花漫 我一把揭開白布相速。 她就那樣靜靜地躺著碟渺,像睡著了一般。 火紅的嫁衣襯著肌膚如雪突诬。 梳的紋絲不亂的頭發(fā)上苫拍,一...
    開封第一講書人閱讀 51,604評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音攒霹,去河邊找鬼怯疤。 笑死,一個(gè)胖子當(dāng)著我的面吹牛催束,可吹牛的內(nèi)容都是我干的集峦。 我是一名探鬼主播,決...
    沈念sama閱讀 40,347評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼抠刺,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼塔淤!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起速妖,我...
    開封第一講書人閱讀 39,253評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤高蜂,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后罕容,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體备恤,經(jīng)...
    沈念sama閱讀 45,702評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,893評(píng)論 3 336
  • 正文 我和宋清朗相戀三年锦秒,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了露泊。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,015評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡旅择,死狀恐怖惭笑,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤沉噩,帶...
    沈念sama閱讀 35,734評(píng)論 5 346
  • 正文 年R本政府宣布捺宗,位于F島的核電站,受9級(jí)特大地震影響川蒙,放射性物質(zhì)發(fā)生泄漏蚜厉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,352評(píng)論 3 330
  • 文/蒙蒙 一派歌、第九天 我趴在偏房一處隱蔽的房頂上張望弯囊。 院中可真熱鬧,春花似錦胶果、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,934評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至撬讽,卻和暖如春蕊连,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背游昼。 一陣腳步聲響...
    開封第一講書人閱讀 33,052評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工甘苍, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人烘豌。 一個(gè)月前我還...
    沈念sama閱讀 48,216評(píng)論 3 371
  • 正文 我出身青樓载庭,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親廊佩。 傳聞我的和親對(duì)象是個(gè)殘疾皇子囚聚,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,969評(píng)論 2 355

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

  • 函數(shù)和對(duì)象 1、函數(shù) 1.1 函數(shù)概述 函數(shù)對(duì)于任何一門語(yǔ)言來(lái)說(shuō)都是核心的概念标锄。通過(guò)函數(shù)可以封裝任意多條語(yǔ)句顽铸,而且...
    道無(wú)虛閱讀 4,564評(píng)論 0 5
  • 第2章 基本語(yǔ)法 2.1 概述 基本句法和變量 語(yǔ)句 JavaScript程序的執(zhí)行單位為行(line),也就是一...
    悟名先生閱讀 4,149評(píng)論 0 13
  • 曾幾何時(shí) 伴著夜的來(lái)臨,是夜蟲的奏鳴 沒(méi)有華麗的光践剂,也沒(méi)有喧囂的鬧 自從有了夜燈 路就不會(huì)寂寞 燈亮鬼譬,在你轉(zhuǎn)身的瞬...
    無(wú)論波濤閱讀 656評(píng)論 0 0
  • 踐行許多天了都沒(méi)有做到詩(shī)文上墻,今天在單位專門打出一首準(zhǔn)備回家上墻舷手。至于打哪一首糾結(jié)了半天拧簸,選了《春曉》,因?yàn)橛X(jué)得...
    夏更幽閱讀 274評(píng)論 0 0
  • 無(wú)論我在何方 心里裝的 永遠(yuǎn)都是你 地球是圓的 所以無(wú)論你走的多遠(yuǎn) 都要回到原點(diǎn) 我不管你走的多遠(yuǎn) 也不管你走了多...
    江瀟然閱讀 341評(píng)論 0 5