函数是否设置在javascript'创建阶段的变量之前?

时间:2016-01-01 23:38:13

标签: javascript

我现在正在做Udemy课程Javascript: Understanding the Weird Parts,我刚刚了解了解释器解释JS时发生的创建阶段和执行阶段。

我有一个问题,但我会首先向您展示我正在玩的代码:

http://codepen.io/rsf/pen/bEgpNY

b();

function b () {

  console.log(a);
}

var a = 'peas';

b();

如果我理解正确,在创建阶段,变量和函数被设置为',这意味着它们在内存中被赋予了斑点。这些变量都给出了undefined的占位符值。然后在执行阶段,引擎执行从顶部开始的行。首次调用b()时,' a'仍然有未定义的占位符值,然后' a'给出了豌豆的初始值'再次调用b()这次' a'有豌豆的价值。 在我看来,这里必须发生两件事之一。备选方案1:在创建阶段,所有变量都在函数之前设置。这意味着当创建函数b()的存储空间时,该函数包含未定义的值(因为已经使用&#39的值创建了' a'内存空间;未定义&#39)。备选方案2:函数和变量按照它们所处的词汇顺序设置(在这种情况下,b在a之前创建),并且当创建b时,' a'引用以某种方式表示该函数正在监听任何可能的“a&a”组合。记忆位置,以及以后的' a'实际创建了位置,引用指的是那个位置。

我是否在这些情景中的正确轨道?

2 个答案:

答案 0 :(得分:2)

你可以这样想。
您的原始代码:

b();

function b () {

  console.log(a);
}

var a = 'peas';

b();

实际上是这样执行的:

var a;
function b () {
  console.log(a);
}

b(); // log undefined because a doesn't have a value yet

a = 'peas';

b(); // log peas because a has a value

基本上所有变量和函数定义都在封闭范围的顶部提升。 顺序并不重要,因为b函数中的代码在您实际调用函数之前不会执行。

答案 1 :(得分:2)

  

如果我理解正确,在创建阶段,变量和函数是'set',这意味着它们在内存中被赋予了斑点。

我不会为此使用术语 set - 它通常用于表示设置为(已分配)特定值的变量。我也不会使用术语“点”或“记忆” - 我们不需要担心这些内部。说声明更清楚。

我也不太喜欢使用术语“创建阶段”,这既是非标准又令人困惑的 - 究竟是什么创造的?我更喜欢“汇编”一词。

  

变量都给出了未定义的占位符值。

确切地说,我不会说它们“具有未定义的值”,而是“没有价值”,或“没有定义”。 undefined不是尚未分配给的变量所持有的值;而是一个状态,这会导致变量在被访问时评估为undefined值。

  

备选方案1:在创建阶段,所有变量都在函数之前设置。

是的,虽然再次使用“set”这个词会让人感到困惑。比如说,“所有变量都是在函数之前声明”。这是提升的过程。

  

备选方案2:函数和变量按照它们所处的词汇顺序设置(在这种情况下,b在a之前创建),当创建b时,'a'引用以某种方式表示函数正在侦听任何可能的'a'存储位置的创建,并且当稍后实际创建'a'位置时,引用指的是该位置。

没有。该功能不会“听”任何东西。它只是在你告诉它时执行。

这很重要吗?

不是真的。它属于奥秘的范畴。因此,我们用规则来阻塞我们的大脑,例如,变量以这种方式提升,函数声明以其他方式提升,let还有其他一些提升行为。在实践中,几乎所有样式指南都会要求您在函数顶部声明变量,如果您没有(或者可以配置这样做),则linters会发出警告。这立即消除了所有可变的提升问题。

有些人喜欢将内部函数放在函数的底部,这样可以正常工作,因为如果它是一个函数声明(即function foo() { }),整个事物(包括定义)就会被提升。如果它是一个赋值给变量的函数表达式(即var foo = function() { }),那么它就是一个变量,我们已经决定将它们放在函数的顶部 - 参见上面的段落。

一般来说,如果你的程序依赖于提升行为,那就写得很糟糕。如果您需要了解提升行为以了解程序的工作原理,那就写得太糟糕了。

总而言之,您真正需要学习的只是一条规则:将变量声明(及其初始化)放在函数的顶部。然后你根本不用担心吊装。

(有一些例外,比如在for语句中声明一个变量,就像在for (var i...)中一样,这很好,假设i没有被用于除{循环的索引。)

出于某种原因,学习JS的人似乎有时会专注于这些奇怪的事情 - 例如“为什么" " == false或其他什么。我建议改为关注如何思考你的问题,并将其分解并编写好的干净的代码,只是有效,你和其他人可以保持而不用担心奥秘。我已经写JS很多年了,不记得上次我遇到与吊装有关的问题。