一抵怎、作用域鏈
當(dāng)執(zhí)行一段JavaScript代碼(全局代碼或函數(shù))時(shí)赃梧,JavaScript引擎會(huì)創(chuàng)建為其創(chuàng)建一個(gè)作用域又稱為執(zhí)行上下文(Execution Context)省核,在頁(yè)面加載后會(huì)首先創(chuàng)建一個(gè)全局的作用域,然后每執(zhí)行一個(gè)函數(shù)航厚,會(huì)建立一個(gè)對(duì)應(yīng)的作用域顷歌,從而形成了一條作用域鏈。每個(gè)作用域都有一條對(duì)應(yīng)的作用域鏈幔睬,鏈頭是全局作用域眯漩,鏈尾是當(dāng)前函數(shù)作用域。
作用域鏈的作用是用于解析標(biāo)識(shí)符溪窒,當(dāng)函數(shù)被創(chuàng)建時(shí)(不是執(zhí)行)坤塞,會(huì)將this、arguments澈蚌、命名參數(shù)和該函數(shù)中的所有局部變量添加到該當(dāng)前作用域中摹芙,當(dāng)JavaScript需要查找變量X的時(shí)候(這個(gè)過(guò)程稱為變量解析),它首先會(huì)從作用域鏈中的鏈尾也就是當(dāng)前作用域進(jìn)行查找是否有X屬性宛瞄,如果沒(méi)有找到就順著作用域鏈繼續(xù)查找浮禾,直到查找到鏈頭,也就是全局作用域鏈份汗,仍未找到該變量的話盈电,就認(rèn)為這段代碼的作用域鏈上不存在x變量,并拋出一個(gè)引用錯(cuò)誤(ReferenceError)的異常杯活。
二匆帚、原型鏈
JavaScript中的每個(gè)對(duì)象都有一個(gè)prototype屬性,我們稱之為原型旁钧,而原型的值也是一個(gè)對(duì)象吸重,因此它也有自己的原型,這樣就串聯(lián)起來(lái)了一條原型鏈歪今,原型鏈的鏈頭是object,它的prototype比較特殊嚎幸,值為null。
原型鏈的作用是用于對(duì)象繼承寄猩,函數(shù)A的原型屬性(prototype property)是一個(gè)對(duì)象嫉晶,當(dāng)這個(gè)函數(shù)被用作構(gòu)造函數(shù)來(lái)創(chuàng)建實(shí)例時(shí),該函數(shù)的原型屬性將被作為原型賦值給所有對(duì)象實(shí)例田篇,比如我們新建一個(gè)數(shù)組替废,數(shù)組的方法便從數(shù)組的原型上繼承而來(lái)凤薛。
當(dāng)訪問(wèn)對(duì)象的一個(gè)屬性時(shí), 首先查找對(duì)象本身, 找到則返回; 若未找到, 則繼續(xù)查找其原型對(duì)象的屬性(如果還找不到實(shí)際上還會(huì)沿著原型鏈向上查找, 直至到根). 只要沒(méi)有被覆蓋的話, 對(duì)象原型的屬性就能在所有的實(shí)例中找到牺氨,若整個(gè)原型鏈未找到則返回undefined奥裸。