91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

javascript聲明提升是什么

發布時間:2020-12-02 13:45:16 來源:億速云 閱讀:172 作者:小新 欄目:web開發

了解javascript聲明提升是什么?這個問題可能是我們日常學習或工作經常見到的。希望通過這個問題能讓你收獲頗深。下面是小編給大家帶來的參考內容,讓我們一起來看看吧!

Javascript聲明提升

在分析聲明提升之前,我認為有必要知道的兩點:

一、引擎查詢變量的兩種方式

引擎查詢變量的方式可以分為LHS和RHS兩種方式,通過“L”和“R”是可以大致了解意思,分別是賦值操作的左側和右側。 (不能光是理解為“=”的左右側可不行,因為賦值操作的形式有多種。)

簡單說下我對這兩種查詢方式的理解:
LHS:賦值操作的目標是誰。 (查詢變量)
RHS:誰是賦值操作的源頭。 (查詢變量的值)

這樣說可能有些難以理解,舉個栗子:

function foo(a){
    //這里存在一個隱式變量分配,LHS查詢變量a,并賦值2.
    //隱式a = 2;
    //左邊LHS查詢變量b,查詢作用域中是否存在b這個變量。
    //右邊RHS查詢變量a的值,將a賦值給b。
    var b = a;
    //返回a,b是RHS查詢變量a的值和變量b的值并使用。
    return a + b;
}
//左邊LHS查詢變量c,查詢作用域中是否存在c這個變量。
//右邊RHS引用函數foo,將2作為參數傳進去。
var c = foo(2);

二、異常

關于異常要強調一點,必須在嚴格模式下。因為在非嚴格模式下,LHS查詢若是在最頂層的全局作用域上找不到查詢的變量,則會創建一個該名稱變量返還給引擎。

ReferenceError:同作用域判別失敗相關。(比如:作用域中遍尋不到所需的變量)
TypeError:作用域判別成功了,但是對結果的操作是非法或不合理的。(比如:試圖對一個非函數類型的值進行函數調用,或者引用null或undefined類型的值中的屬性)

舉個栗子:

"strict"
function foo() {
    console.log(a) //undefined
    console.log(b) //ReferenceError
}
var a = 2;

聲明提升

一、初步了解

編寫javascript代碼時,很多時候都會覺得代碼會自上而下的執行。但是碰到聲明提升,這種想法就會被打破。

舉個栗子:

a = 2;
var a;
console.log(a);

運行結果為: 2

如果按照常理的自上而下執行,那么a執行的預期結果應當是undefined,然而為什么會是2?
這就是聲明提升的結果。

二、進一步了解

當初步了解聲明提升的時候,碰上下面的代碼:

console.log(a);
var a = 2;

運行結果為:undefined

初步了解聲明提升之后,會自然而然的認為,聲明就會被提升,然而聲明的時候賦值,卻得不到變量的值。

其實,上面代碼的運行步驟可以分解為:

var a; //聲明提升
console.log(a); //打印a的值
a = 2; //對a進行賦值

原來,聲明提升就是字面上的聲明提升,其余的操作(如:賦值和其他邏輯)都還在原地踏步。

聲明一個函數進行相應的操作,會得到函數聲明提升的結果。由此可以發現:變量和函數的聲明都會被提升在其他代碼的前面執行。

三、逐步了解

通過幾次試驗可以逐步了解到,其實聲明提升就是:變量和函數的聲明會被提升在其他代碼(當前作用域)的前面執行。

走到這里,有人就會想到,要是函數表達式,也會進行提升嗎?

答案是:不會。而且,即使是具名函數表達式,在名稱標識符賦值之前也是不能使用的。

舉個栗子:

foo(); //TypeError
bar(); //ReferenceError
var foo = function bar(){};

代碼分解為:

var foo; //變量聲明提升
foo(); //foo對undefined值進行函數調用導致非法操作,故TypeError
bar(); //bar函數并沒有聲明,故ReferenceError
foo = function bar(){}; //對foo進行賦值

所以:函數表達式在名稱標識符賦值之前是不能使用的。

注意:1、每個作用域都會進行提升操作。(所以函數內部形成的作用域也會有提升操作,提升            操作僅限當前的函數內部作用域)
2、在函數和變量提升時,函數優先提升。
3、一個普通塊內部的函數聲明通常會被提升到所在的作用域的頂部。

四、深入了解

在閱讀《你不知道的javascript》時,學習let的過程中,會發現有說明提到:使用let進行的聲明不會在作用域中進行提升。聲明的代碼在被運行之前是,聲明并不存在。

舉個栗子:

console.log(a);
let a = 2;

運行結果是:ReferenceError: Cannot access 'a' before initialization. //初始化前無法訪問"a"

然后回到之前我運行的代碼,將let換為var,返回的結果是undefined。

二者結合,再加上閱讀我用了兩個月的時間才理解let這篇文章,發現對let是否提升有了一個更新的認識。

作者把js變量分成三部分操作:創建(create)、初始化(initialize)和賦值(assign)

上面的操作之所以會有不同的響應并不是說let沒有創建,而是有一個初始化的過程并沒有執行。而在初始化之前使用變量,就會形成一個暫時性死區

經過var和let和function的測試可以總結到:

var的創建和初始化被提升,賦值不會被提升。

let的創建被提升,初始化和賦值不會被提升。

function的創建、初始化和賦值均會被提升。

感謝各位的閱讀!看完上述內容,你們對javascript聲明提升是什么大概了解了嗎?希望文章內容對大家有所幫助。如果想了解更多相關文章內容,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

秭归县| 五大连池市| 阿坝县| 德钦县| 淳化县| 舟山市| 噶尔县| 阿鲁科尔沁旗| 丘北县| 常熟市| 习水县| 增城市| 石屏县| 同德县| 太仆寺旗| 南雄市| 潼关县| 久治县| 镇康县| 鹤庆县| 新田县| 若尔盖县| 镇宁| 体育| 黎平县| 嘉祥县| 抚顺县| 秦皇岛市| 宁城县| 陆良县| 彭泽县| 时尚| 宜川县| 宁安市| 揭西县| 浦东新区| 稻城县| 巴彦县| 通江县| 辛集市| 青阳县|