国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

5分鐘深入了解js變量提升

tinysun1234 / 1405人閱讀

摘要:對于大多數開發者來說,變量提升可以說是一個非常常見的問題,但是可能很多人對其不是特別的了解。如果說擁有和一樣的變量提升效果的話,那么應該是輸出。而和它們的變量提升的效果是一樣的,也都存在著臨死性死區的概念。

對于大多數js開發者來說,變量提升可以說是一個非常常見的問題,但是可能很多人對其不是特別的了解。所以在此,我想來講一講。

先從一個簡單的例子來入門:

a = 2;
var a;

console.log(a);

你覺得以上的代碼會輸出什么?是輸出undefined嗎?如果是按照程序的自上而下執行的話,那么這一段代碼確實是輸出undefined,因為var a語句把a = 2的語句給覆蓋了。然而,javascript并不是嚴格的自上而下執行的語言。

這一段代碼的輸出結果是2,是不是感到很意外?為什么會這樣呢?這個問題的關鍵就在于變量提升(hoisting)。它會將當前作用域的所有變量的聲明提升到程序的頂部,因此上面的代碼其實等價于以下代碼。這樣是不是就很簡單明了了。

var a;
a = 2;

console.log(a);

那么接下來,我們再來看這個例子。

console.log(a);

var a = 2;

你覺得以上的代碼會輸出什么?是直接報ReferenceError嗎?還是輸出2呢?

其實以上代碼會輸出undefined。為什么呢?我們之前說過,js會將變量的聲明提升到頂部,可是賦值語句并不會提升。所以對于js來說,其實var a = 2是分為兩步的:

var a;

a = 2;

而js只會將第一步提升到頂部,所以上面的語句等價于:

var a;

console.log(a);

a = 2;
為什么有變量提升

那么為什么會出現變量提升這個現象呢?

js和其他語言一樣,都要經歷編譯和執行階段。而js在編譯階段的時候,會搜集所有的變量聲明并且提前聲明變量,而不會改變其他語句的順序,因此,在編譯階段的時候,第一步就已經執行了,而第二步則是在執行階段執行到該語句的時候才執行。

變量聲明

js的變量聲明其實大體上可以分為三種:var聲明、let與const聲明和函數聲明。

函數聲明與其他聲明一起出現的時候,就可能會引起一些困擾。我們來看下面的例子。

foo();

function foo() {
    console.log("foo");
}
var foo = 2;

你覺得上面會輸出什么?TypeError嗎?還是輸出foo呢?想一想再接著往下看。

當當當當,其實最后輸出的結果是foo。這就引出了我們的問題了,當函數聲明與其他聲明一起出現的時候,是以誰為準呢?答案就是,函數聲明高于一切,畢竟函數是js的第一公民。

那么,下面的例子呢?

foo();

function foo() {
    console.log("1");
}

function foo() {
    console.log("2");
}

當出現多個函數聲明,那怎么辦呢?

上面這個代碼輸出結果為2。因為有多個函數聲明的時候,是由最后面的函數聲明來替代前面的。

想必經歷了以上的例子,你應該已經對變量聲明已經有一定的了解了。那么我再來出一道題目來測試下。

foo();

var foo = function() {
    console.log("foo");
}

這道題目是不是非常簡單啊?這道題和上面的第二道例子其實是一樣的。var foo = function() {}這種格式我們叫做函數表達式。

它其實也是分為兩部分,一部分是var foo,而一部分是foo = function() {},參照例2,我們可以知道,這道題的結果應該是報了TypeError(因為foo聲明但未賦值,因此foo是undefined)。

上面我們提到了var聲明,函數聲明,那么接下來我們來講講let和const聲明。

let和const其實也是有函數提升的概念,不過它們會比較特殊,與var不一樣,它們存在一個臨死性死區的概念。我們可以通過一個例子來體現這一點。

var a = 2;
function test() {
    console.log(a);
    let a = 5;
}
test();

你覺得上面的代碼會輸出什么呢?是輸出2,還是undefined呢?

如果說,let沒有變量提升的效果的話,那么應該是輸出2。如果說let擁有和var一樣的變量提升效果的話,那么應該是輸出undefined。然而,其實上面的代碼是會報錯的。會報"ReferenceError: a is not defined"錯誤。那么為什么呢?

這其實就是我說的,let雖然具有變量提升的功能,但是它又與var不一樣,它具有一個臨死性死區的概念。

臨死性死區其實就是說,a我已經聲明了,可是在沒有到它賦值的時候,你都不能使用這個變量,不然就會報錯。所以該當前作用域開始,一直到let a = 5為止這整一塊,都是a變量的臨死性死區,你不能使用它。

而const和let它們的變量提升的效果是一樣的,也都存在著臨死性死區的概念。

總結

那么接下來我們來總結一下。

js會將變量的聲明提升到js頂部執行,因此對于這種語句:var a = 2;其實上js會將其分為var a;和a = 2;兩部分,并且將var a這一步提升到頂部執行。

變量提升的本質其實是由于js引擎在編譯的時候,就將所有的變量聲明了,因此在執行的時候,所有的變量都已經完成聲明。

當有多個同名變量聲明的時候,函數聲明會覆蓋其他的聲明。如果有多個函數聲明,則是由最后的一個函數聲明覆蓋之前所有的聲明。

let和const都具有變量提升的效果,但是它們都具有臨死性死區,從作用域開始部門,一直到變量的聲明語句這整一塊,你都不能使用該變量。

以上,就是本文的內容。覺得有用的話麻煩點個贊,嘻嘻。

本文地址在->本人博客地址, 歡迎給個 start 或 follow

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/98942.html

相關文章

  • JavasScript重難點知識

    摘要:忍者級別的函數操作對于什么是匿名函數,這里就不做過多介紹了。我們需要知道的是,對于而言,匿名函數是一個很重要且具有邏輯性的特性。通常,匿名函數的使用情況是創建一個供以后使用的函數。 JS 中的遞歸 遞歸, 遞歸基礎, 斐波那契數列, 使用遞歸方式深拷貝, 自定義事件添加 這一次,徹底弄懂 JavaScript 執行機制 本文的目的就是要保證你徹底弄懂javascript的執行機制,如果...

    forsigner 評論0 收藏0
  • 你需要知道面試中的10個JavaScript概念

    摘要:自我學習目前有成千上萬的年輕人在學習和開發,希望獲得一份工作。知道的綁定規則。知道和原型屬性是什么以及它們的作用。高階函數了解函數是中的一級對象,這意味著什么知道從另一個函數返回函數是完全合法的。了解閉包和高階函數允許我們使用的情況。 翻譯原文出處:10 JavaScript concepts you need to know for interviews 之前不是鬧得沸沸揚揚的大漠窮...

    YacaToy 評論0 收藏0
  • 體驗jaivascript之美第二課 全局對象、外部環境、聲明提升

    摘要:全局對象在程序任何地方都能訪問到的對象,在瀏覽器中是變量指向在中是什么外部環境暫時不講。函數聲明直接提前。執行過程,函數執行和銷毀過程。變量預解析,賦值外部環境之間的關系。如果做不對,繼續找,直到合格。 當程序在瀏覽器中運行的時候,js引擎會產生三個東西。 showImg(https://segmentfault.com/img/bVMjv4?w=890&h=422);1.全局對象 ...

    icyfire 評論0 收藏0
  • 從國企到阿里的面試經歷(一)

    摘要:月初,一個和我關系不錯的阿里朋友,在內網看到一個開發專家的崗位,挺適合我,便問我有沒有興趣。正式開始電面正式開始,下文中阿里面試官簡稱。晚上點左右,接到阿里影業的來電,我趕緊帶好耳機接起電話。 讀完本文需要 3 分鐘。 首先,跟大家說聲抱歉,年后實在是太忙,帶娃、錄視頻、換工作,大堆事情擠在一起,一不小心就斷更了 4 個月,實在是對不起一直以來支持我的朋友們。 從今天開始,我盡量堅持...

    justjavac 評論0 收藏0

發表評論

0條評論

tinysun1234

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<