JavaScript變量提高的相關討論

2017年的事情仍是2017年完成吧。話很少說,如今開始:javascript

以前翻譯過兩篇發表在Medium上的兩篇文章,關於變量和函數提高的問題。後來發現,一個讀者(Gavin Orland)與做者(Bhuvan Malik)就函數和變量提高的問題產生了分歧,是留言形式的。最後做者還專門又寫了一篇文章來回應問題,我想也是想讓你們都看見吧。因此我本身整理一下,現將他們的討論也作一個搬運吧。java

Gavin Orland 與 Bhuvan Malik 就提高話題中「問題1」和「問題3」的討論

Gavin Orland
Explanations 1 and 3 are slightly incorrect as function declarations are actually hoisted above variable declarations.
解釋1和3有點不正確,實際上函數聲明其實是在變量聲明之上提高的。git

Bhuvan Malik:
For the first question’s behind the scenes, I have purposely shown the effects of hoisting only inside the functional scope of b().
對於第一個問題,我刻意僅在b()的功能範圍內展現了提高的效果。github

As for the third question, var hoisted = 「I’m a variable」; comes first and therefore the variable 「hoisted」 should be hoisted first with an 「undefined」 value. I could be wrong in which case you can point me to a source which proves me wrong, in which case I’d be happy make the change. ?
第三個問題:var hoisted = 「I‘m a variable’」; 所以首先應該提高「提高」的變量,而且具備「undefined」的值。我多是錯的,在這種狀況下,你能夠指出個人來源,證實我錯了,在這種狀況下,我會很高興作出改變。?app

Gavin Orland
Here’s what goes on behind the scenes for explanation 3:ide

function parent() {  
// Function declaration hoisted first  
    function hoisted() { 
        return "I'm a function"; 
    } 
// Variable re-assigned (declaration ignored) 
 hoisted = "I'm a variable";  
return hoisted(); 
} 
console.log(parent());

Here’s a source for this.
源碼在這裏。函數

Bhuvan Malik
What you’re trying to say is correct. However, saying that function declarations get hoisted 「above」 variable declarations, which implies that variable declarations 「get hoisted below」 is wrong. In such a case, what is happening is that the hoisting of var declarations simply gets ignored. I will update this. ?
你想證實你說的是對的。然而說函數聲明提高在變量聲明提高之上,在暗示變量聲明「提高在下面」是錯的。在這樣的狀況下,發生的事情就是簡單地忽略var聲明的提高。 我會更新這個。?學習

Gavin Orland
I’m not 「trying」 to say anything, I’m simply saying it: function declarations are hoisted above variable declarations. What is unclear about that? Yes, therefore variable declarations are then logically hoisted below function declarations, if you want to think about it like that. It is not wrong to say that — please prove to me that is wrong.
我沒有試着說什麼,我只是在說:函數聲明被提高到了變量聲明之上。有什麼不清楚的呢?是的,所以變量聲明在函數聲明下面邏輯地提高,若是你以爲他是這樣,那樣說也沒錯--請向我證實我是錯的。this

In your first reply you said:
在你第一次回覆中你說翻譯

var hoisted = 「I’m a variable」; comes first and therefore the variable 「hoisted」 should be hoisted first with an 「undefined」 value

This is incorrect — a declaration will be hoisted after the function with this value. Then the string value is immediately assigned to it.
這是錯的-- 一個聲明將在具備這個值的函數以後被提高。而後,字符串值當即分配給它。

Indeed, in the case of example 3, the declaration is ignored (in contradiction to your explanation), as I explained, because the variable has already been declared in the form of the function, but in other cases (such as example 1, which you do not want to correct) function declarations are hoisted first, then variable declarations.
確實,在案例3的狀況中,這個聲明被忽略(與你的解釋相矛盾),正如我所解釋的,由於變量已經以函數的形式被聲明瞭,但在其餘狀況(如示例1,您不想糾正)函數聲明首先被提高,而後是變量聲明。

Function and variable declarations are always hoisted in this manner, the assignment to the variable will take place wherever it appears in the code.
函數和變量聲明老是用這樣的方式被提高,變量的賦值將在代碼中的任何位置出現。

It’s odd you should accept my correction and then somehow claim you are right and I am wrong?! Anyway, I see you have now corrected the article (otherwise very good, and thanks for writing it).
這很奇怪,你應該接受個人更正,而後以某種方式聲稱你是對的,我錯了?不管如何,我看你如今已經糾正了這篇文章(其餘的很是好,謝謝你寫了這些)。

Bhuvan Malik
First of all, thanks for correcting me sir and I appreciate your explanations. You say that variable declaration will get hoisted after the function with an 「undefined」 value, and then the string value will be immediately assigned. My doubt here is that what if we only have the variable declaration without a string value being assigned like so:
首先,感謝先生糾正我,我感謝你的解釋。你說那個變量聲明在函數以後被賦值「undefined」,而後字符串值將當即分配。這裏個人疑問是,若是咱們只有變量聲明沒有被賦值的字符串值,以下所示:

function parent() { 
    var hoisted;
    function hoisted() {  
        return "I'm a function"; 
    } 
    return hoisted(); 
} 
console.log(parent());

If variable declaration does get hoisted after the function, then behind the scenes for this according to your explanation should be:
若是變量聲明在函數以後被掛起,那麼根據你的解釋,這個後臺應該是:

function parent() {  
    // Hoisted first  
    function hoisted() { 
        return "I'm a function"; 
    } 
    // Hoisted second with a value of undefined
    var hoisted; return hoisted(); 
} 
console.log(parent());

If the variable declaration is indeed hoisted second, then hoisted should finally get the value of 「undefined」 after the hoisting of the function and the program should finally throw an error because hoisted is no longer a function.
若是變量聲明確實是第二次提高的話,那麼在提高函數後最終獲得的值是「undefined」,程序最終會由於提高函數而拋出一個錯誤。

However, the output still comes out to be 「I’m a function」.
然而,這裏輸出的是「I’m a function」

This is the reason why I think there is no variable declaration hoisting happening here. I agree that a variable declaration hoisting in such a case simply gets ignored. Getting me?
Again, I could be wrong. I’m just trying to learn here by discussing with you.
就是這個緣由我認爲變量聲明沒有提高。 我贊成,在這種狀況下提交的變量聲明只是被忽略。 再聯繫我?再次,我多是錯的。 我只是想經過討論和你一塊兒來學習。

Gavin Orland
No problem, I can explain this. In fact I think we have already covered it, really.
沒問題,我能解釋這個。事實上我認爲咱們已經把它覆蓋了,真的。

Variable declarations are hoisted after (or below) function declarations. But, in the case where the names match function declarations (or any variable already declared), they have no effect, so are ignored.
變量聲明在函數聲明以後(或者下面)被提高。可是,在名稱匹配函數聲明的狀況下(或任何已經聲明的變量),它們沒有效果,所以被忽略了。

So, redeclaring a variable does not render it undefined, it has no effect. Only re-assigning an already declared variable has an effect.
所以,從新聲明變量不能給與它「undefined」,這沒有效果。只能從新給一個已經聲明的變量分配纔會有效果。

Here’s a simple but illuminating example of this variable hoisting, btw:
這是個關於變量提高的簡單又又明確例子:

console.log(x); // undefined 
var x = y; 
function y(){} 
console.log(x); // function y(){}

This is understood as:
這被理解爲:

function y(){} 
var x;  
console.log(x); // undefined 
x = y;  
console.log(x); // function y(){}

Bhuvan Malik:
Got it now. Thank you so much!
如今明白了。 很是感謝!

以上就是這位讀者(Gavin Orland )和做者(Bhuvan Malik)之間的討論。仍是獲得些啓發。由於讀者給的源碼但是大名鼎鼎的《你不知道的JavaScript》裏面的例子。我也算完成了搬運,好了~ 能夠沒有欠債(我本身的債)的度過2017了。

Peace ✌️

相關文章
相關標籤/搜索