JavaScript 提升解释

47

以下代码段有何不同?

var a = 0;
function b(){
    a = 10;
    return function a(){};
}
b();
console.log(a);  // => 10

并且

var a = 0;
function b(){
    a = 10;
    return
    function a(){};
}
b();
console.log(a);  // => 0

这与JavaScript变量提升有关,但我对该概念的理解恰好产生了相反的输出。

Translated: 这跟 JavaScript 中的变量提升有关,但是我的理解恰好得到了相反的结果。

15
当在行内使用return关键字时,它会执行该操作,即“返回并退出函数b()”,JavaScript会自动在其后添加分号;。请注意保持原文意思不变,同时将语言更改为通俗易懂的语言。 - Asons
2
函数声明在任何代码执行之前就被处理(所谓的“提升”),因此它们放置的位置并不重要,它们总是会被评估。 - RobG
4个回答

56
return function a(){};

这里的function ...是一个表达式。确切地说,是一种命名函数表达式。这里的a并不太重要,它只是给匿名函数一个.name,但你返回的仍然只是一个函数表达式。

return 
function a(){};

这里相当于:

return;
function a(){};

这里的function a是一个声明而不是表达式。它被提升,创建了一个本地名称a在该作用域中,遮蔽了外部的a。也就是说它等同于:

function b(){
    var a = function () {};
    a = 10;
    return;
}

感谢@deceze,我错过了注意到第一个片段中的function a()是函数表达式,而在第二个片段中是函数声明。而且,函数表达式只有在到达该行时才被定义,而函数声明则在其周围的函数或脚本执行时立即定义。 - SnapADragon

26
return
function a() {}

等同于

return;
function a() {}

在自动分号插入后。 在第二种情况中,函数a被移动到其作用域的顶部。代码与原来相同。

var a = 0;

function b() {
  function a() {};
  a = 10;
  return;
}
b();
console.log(a);

b()内部的a函数被覆盖后,无法从b()外部访问。

以下是演示如何使用变量提升的示例。

var a = 0;

function b() {
  console.log(a); // function
  a = 10;
  console.log(a); // 10
  return

  function a() {};
}
console.log(b()); // undefined
console.log(a);


1
谢谢Tushar,但我想知道为什么在第一个片段中**function a()**没有被提升,而在第二个片段中它被提升了。@deceze在他的回答中解释得很好。 - SnapADragon
@SnapADragon那么为什么这个问题的赞数比它还多呢? - I am the Most Stupid Person
1
因为Tushar的回答可能更适合其他人,但@deceze解释了我正在寻找的内容。这样还满意吗? - SnapADragon

1

换行符可以代替分号

这样做

var a = 0;
function b(){
    a = 10;
    return // line-break
    function a(){};
}
b();
console.log(a);  // => 0

means这样:

var a = 0;
function b(){
    a = 10;
    return; // <-- 'adds this semicolon'
    function a(){};
}
b();
console.log(a);  // => 0

如果您需要这个换行符,您可以像这样进行操作:
var a = 0;
function b(){
    a = 10;
    return (
        function a(){}
    )
}
b();
console.log(a);

-1
让我们假设一下。
你正在玩板球。投球手正准备好投球,而你只是在空中挥动了你的球棒。
这算击球吗?不算!
因此,如果我们把抬杆比作板球,那么在投球手没有投出球之前,击球是没有意义的。
快速示例:
抬杆
console.log('batsman hit but ', ballStatus()); // batsman hit but  true


function ballStatus() {
    return true;
}

未提升

 console.log('batsman hit but ', ballStatus()); // Uncaught TypeError: ballStatus is not a function

 var ballStatus = function() {
    return true;
 }


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接