函数声明优先/覆盖变量声明?起重?为什么?

时间:2017-09-02 15:33:51

标签: javascript memory functional-programming variable-declaration function-declaration

摘录1:



var a; // undefined variable named 'a'
function a(foo) { // a function named 'a'
  var foo = "Hello World";
  console.log(foo);
}
console.log(a); // output is: [Function: a], but why not undefined?




摘录2:



function a(foo) { // a function named 'a'
    var foo = "Hello World";
    console.log(foo);
}
var a; // undefined variable named 'a'
console.log(a); // output is: [Function: a], but why not undefined?




我本来可以向Snippet 1展示这个问题 - 不过我只是为了完整性而展示了这两个问题。我也在其中写了一些简短的评论。

我的问题是,在这两种情况下,为什么函数声明“覆盖”/“阴影”或对变量声明采用“优先级”?有人可以解释一下这种行为吗?

据我所知,从最终结果来看,这些可以说是相同的(从解释者的角度来看),因为“提升”现象,但为什么执行功能声明或变量声明在Javascript引擎解释/解析时优先 优先 创建 阶段)?即哪一个悬挂在另一个之上?我已经读过它是函数声明优先于变量声明 - 但为什么就是这种情况?

另外,请参考第一个代码段(但这适用于这两种情况),是第一行声明的'a'的内存位置/地址,第6行是完全正确的相同?而且,因为'a',在代码的两个中代表函数声明,解析第1行和第6行后,在其内存位置/地址处的'strong'值是多少?在创建阶段?由于功能声明已被提升,因此#?在变量声明之上,这是否意味着在第1行,' a的内存地址指向功能对象' a' ,结束时执行上下文的创建阶段?

代码段中,'var a'未定义,因此为什么 不是' t 'a当我们到达 执行 阶段(执行点从第6行开始?)时,未定义的价值< / strong> Javascript引擎是否只是说“啊,如果我们允许'var a'''覆盖''函数a(){...}',它将继续未定义,因此无法使用。然而,如果我们允许'a'来表示所述函数,那么至少用户可以调用所述函数(甚至在其声明之前,而不会得到参考错误)&#34;。这不太可能是这种情况,但听起来合乎逻辑/理想,可能吗?

所以,我的问题是:

  1. 为什么函数声明被覆盖或优先于变量声明的原因是什么?这是我们刚才接受的原因,因为它是ECMAScript规范的实现,还是我们可以解释这种行为?
    1. 如果可能,有人可以回答内存中发生的事情,当这一过程中每一步都发生这种情况吗?
    2. 在过去的8个小时里,我一直试图运用自己的直觉(我最终陷入了JavaScript其他特性的另一个维度,但这本身就是另一个问题)但是我想知道是否有一个简单的或者具体解释或回答这种行为。

      理解所有这些的任何帮助都将非常感激。

2 个答案:

答案 0 :(得分:3)

  

我的问题是,在这两种情况下,为什么函数声明'覆盖'/'遮蔽'或对变量声明采取'优先'?有人可以解释一下这种行为吗?

在任一片段中只有一个位置,变量a被赋予一个值,而这是函数声明。声明var a;表示&#34;我宣布名为a的变量存在&#34;。由于函数声明正在处理声明它存在给它一个值,var a;语句实际上没有任何效果。

事实上,如果我们引用JavaScript规范的Section 10.5.8,我们可以看到此var a;的最终结果实际上什么都不做,因为已经声明了a变量到处理var a;声明时。

  

据我所知,由于“提升”现象,这些可能与最终结果相同(从解释者的角度来看),但为什么函数声明或变量声明优先于其他声明。它是在创建阶段由Javascript引擎解释/解析的吗?

没有采取任何措施&#34;优先&#34;这里。只有一个名为a的变量。 var a;未向a提供值,因此它对a的值没有影响。

  

另外,请参考第一个代码片段(但这适用于两种情况),是第1行声明的“a”的内存位置/地址,第6行是否完全相同?

只有一个a变量,它只占一个值,所以这个问题大多是荒谬的,但粗略地说,a变量本身只存在于一个地方,它会只引用一个值(内存位置),这将是该函数的定义。

  

由于功能声明已被提升,因此#&#39;在变量声明之上,这是否意味着在第1行,&#39;在执行上下文创建阶段结束时,内存地址指向函数对象&#39; a&#39; ?

我对创建阶段的了解并不是很好,但在此代码的执行过程中,a只引用一个值,如上所述。

  

在两个代码片段中,'var a'未定义,那么为什么在我们到达执行阶段(其执行点从第6行开始?)时,'a'值是未定义的值?

请参阅我的第一和第二个答案。

  

为什么函数声明被覆盖或优先于变量声明的原因是什么?和

正如我所说,它没有采取&#34;优先级&#34;,但JavaScript具有功能提升的原因是为了允许人们在代码中从一行中调用函数函数的实际定义,类似于C#和Java等其他主要语言。

  

如果可能的话,有人可以回答每一步中发生的事情吗?

JavaScript规范没有定义内存中发生的事情。它定义了代码的外部行为。所以这将是一个实现细节,并且将是引擎特定的。

这是对代码执行时发生的事情的粗略打击(在两种情况下):

  1. 创建一个名为a的变量,并为其指定该函数的值。
  2. 检查是否存在名为a的变量。已经有一个,所以什么都不做。
  3. 执行console.log并传递a的值(即该功能)

答案 1 :(得分:0)

函数声明在变量提升之前被提升。

console.log(a);

var a = 42; // assignment

console.log(a);

function a(foo) { // a function named 'a'
  var foo = "Hello World";
  console.log(foo);
}

console.log(a);