资讯专栏INFORMATION COLUMN

JavaScript变量提升的相关讨论

gxyz / 1099人阅读

摘要:函数和变量声明总是用这样的方式被提升,变量的赋值将在代码中的任何位置出现。然而,这里输出的是就是这个原因我认为变量声明没有提升。变量声明在函数声明之后或者下面被提升。这是个关于变量提升的简单又又明确例子这被理解为现在明白了。

2017年的事情还是2017年完成吧。话不多说,现在开始:

之前翻译过两篇发表在Medium上的两篇文章,关于变量和函数提升的问题。后来发现,一个读者(Gavin Orland)与作者(Bhuvan Malik)就函数和变量提升的问题产生了分歧,是留言形式的。最后作者还专门又写了一篇文章来回应问题,我想也是想让大家都看见吧。所以我自己整理一下,现将他们的讨论也做一个搬运吧。

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有点不正确,实际上函数声明实际上是在变量声明之上提升的。

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()的功能范围内展示了提升的效果。

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”的值。我可能是错的,在这种情况下,你可以指出我的来源,证明我错了,在这种情况下,我会很高兴做出改变。?

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

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.
我没有试着说什么,我只是在说:函数声明被提升到了变量声明之上。有什么不清楚的呢?是的,因此变量声明在函数声明下面逻辑地提升,如果你觉得他是这样,那样说也没错--请向我证明我是错的。

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 ✌️

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/90575.html

相关文章

  • 译: 函数提升提升面试相关问题

    摘要:函数提升在里有两种方式创建函数,通过函数声明和函数表达式。函数声明用指定的参数来定义函数。提示不要在中进行函数声明。问题输出两个都是用函数声明的函数,将被提升到的局部作用域顶端。函数本身将作为函数声明在全局范围内提升。 作者关于提升的话题,总共有两篇。(后来又有一个讨论篇),再次搬过来。水平有限,如果翻译的不准确请包涵,并去看原文。下面开始: 这是我之前的关于提升的文章,标题为《用le...

    wuaiqiu 评论0 收藏0
  • 前端每周清单半年盘点之 JavaScript

    摘要:前端每周清单专注前端领域内容,以对外文资料的搜集为主,帮助开发者了解一周前端热点分为新闻热点开发教程工程实践深度阅读开源项目巅峰人生等栏目。背后的故事本文是对于年之间世界发生的大事件的详细介绍,阐述了从提出到角力到流产的前世今生。 前端每周清单专注前端领域内容,以对外文资料的搜集为主,帮助开发者了解一周前端热点;分为新闻热点、开发教程、工程实践、深度阅读、开源项目、巅峰人生等栏目。欢迎...

    Vixb 评论0 收藏0
  • 前端每周清单第 43 期:2017 JavaScript 回顾、Rust 与 WebAssembly

    摘要:杨冀龙是安全焦点民间白帽黑客组织核心成员,被浪潮之巅评为中国新一代黑客领军人物之一他在本文中依次分享了对于黑客的定义如何从黑客成为一名安全创业者技术创业踩过的坑给技术创业者建议等内容。 showImg(https://segmentfault.com/img/remote/1460000012377230?w=1240&h=796); 前端每周清单专注前端领域内容,以对外文资料的搜集为...

    xorpay 评论0 收藏0
  • 理解 JavaScript(二)

    摘要:所以形式参数是本地的,不是外部的或者全局的。这叫做函数声明,函数声明会连通命名和函数体一起被提升至作用域顶部。这叫做函数表达式,函数表达式只有命名会被提升,定义的函数体则不会。 Scoping & Hoisting var a = 1; function foo() { if (!a) { var a = 2; } alert(a); }; ...

    luxixing 评论0 收藏0
  • ES6 变量作用域与提升变量生命周期详解

    摘要:不同的是函数体并不会再被提升至函数作用域头部,而仅会被提升到块级作用域头部避免全局变量在计算机编程中,全局变量指的是在所有作用域中都能访问的变量。 ES6 变量作用域与提升:变量的生命周期详解从属于笔者的现代 JavaScript 开发:语法基础与实践技巧系列文章。本文详细讨论了 JavaScript 中作用域、执行上下文、不同作用域下变量提升与函数提升的表现、顶层对象以及如何避免创建...

    lmxdawn 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<