js除了全局作用域之外富寿,只有函數(shù)可以創(chuàng)建的作用域沉衣。所以改橘,我們在聲明變量時(shí)貌夕,全局代碼要在代碼前端聲明,函數(shù)中要在函數(shù)體一開始就聲明好。除了這里兩個(gè)地方开泽,其他地方都不要出現(xiàn)變量聲明荞彼,而且建議使用“單var"形式站绪。
如圖贴唇,全局代碼和fn、bar兩個(gè)函數(shù)都會(huì)形成一個(gè)作用域栋艳。而且恰聘,作用域有上下級(jí)的關(guān)系,上下級(jí)關(guān)系的確定就要看函數(shù)是在那個(gè)作用域下創(chuàng)建的。作用域最大的用處就是隔離變量晴叨,不同作用域下同名變量不會(huì)有沖突凿宾。
作用域是在函數(shù)定義時(shí)就已經(jīng)確定,而不是像執(zhí)行上下文環(huán)境等到函數(shù)調(diào)用時(shí)才產(chǎn)生兼蕊。而且菌湃,對(duì)函數(shù)不同的調(diào)用就會(huì)產(chǎn)生不同的上下文環(huán)境。
作用域只是一個(gè)“地盤”遍略,一個(gè)抽象的概念,其中沒有變量骤坐。要通過作用域?qū)?yīng)的執(zhí)行上下文環(huán)境來獲取變量的值绪杏。同一個(gè)作用域下,不同的調(diào)用會(huì)產(chǎn)生不同的執(zhí)行上下文環(huán)境纽绍,繼而產(chǎn)生不同的變量的值蕾久。所以,作用域中變量的值是在執(zhí)行過程中產(chǎn)生確定的拌夏,而作用域確實(shí)在函數(shù)創(chuàng)建時(shí)就確定了僧著。如果要查找一個(gè)作用域下某個(gè)變量的值,就需要找到這個(gè)作用域?qū)?yīng)的執(zhí)行上下文環(huán)境障簿,再在其中尋找變量的值盹愚。
自由變量:在某個(gè)作用域中使用的變量x,卻沒有在該作用域中聲明(即在其他作用域中聲明的)站故,對(duì)于該作用域來說皆怕,x就是一個(gè)自由變量。
var x = 10;
function fn(){
var b = 20;
console.log(x+b); //x 就是一個(gè)自由變量西篓。
}
無論如何愈腾,在fn中,x的取值要在創(chuàng)建fn函數(shù)的那個(gè)作用域中取值岂津,是創(chuàng)建虱黄,而不是調(diào)用。如果在創(chuàng)建fn函數(shù)的那個(gè)作用域還沒找到吮成,則繼續(xù)往上的作用域找橱乱,一直找到全局作用域,如果全局作用域都沒找到赁豆,那就是沒有了仅醇。這個(gè)一步步跨的路線,我們就稱之為--作用域鏈魔种。