JavaScript“提升”

IT技术 javascript hoisting
2021-02-10 16:50:12

我遇到了 JavaScript 'hoisting',但我没有弄清楚这段代码是如何真正起作用的:

var a = 1;

function b() {
    a = 10;
    return;

    function a() {}
}

b();
alert(a);

我知道像 ( function a() {})这样的函数声明将被提升到函数b作用域的顶部,但它不应该覆盖的值a(因为函数声明覆盖变量声明而不是变量初始化)所以我预计警报的值会是 10 而不是 1!!

5个回答
  1. 全局a设置为1
  2. b() 叫做
  3. function a() {}被提升并创建一个局部变量a来掩盖全局a
  4. 本地a设置为10(覆盖函数a
  5. 全局a(仍然1)被警告
所以如果a没有提升,调用函数b()a = 10全局设置alert(a)然后输出10?如果我理解正确?
2021-03-14 16:50:12
理解提升的最好方法是像编译器一样说话,Grate
2021-03-14 16:50:12
@Quentin:你能用代码展示一下这个函数在提升时的样子吗?
2021-03-17 16:50:12
@Brown_Dynamite — 看起来像是在问题中。它按照本答案中描述的顺序运行。
2021-03-31 16:50:12
谢谢@Quentin 我错过了事实编号 3(该函数 a() {} 创建了一个局部变量来掩盖全局 a)
2021-04-09 16:50:12

这是因为这个例子中编译/解释的顺序有点误导。function a () {}行在执行函数的任何其余部分之前被解释,因此在函数的最开始处,a其值为function a () {}当您将其重新分配给 时10,您正在重新分配afunction 局部范围内的值b(),一旦返回,该值就会被丢弃,而将 的原始值保留a = 1在全局范围内。

您可以通过alert()在适当的位置放置s 等来验证这一点,以查看a各点处的值

(1) JavaScript 没有块语句作用域;相反,它对于块所在的代码是本地的。

(2) Javascript 在函数作用域中的变量声明,这意味着在函数中声明的变量在该函数的任何地方都可用,甚至在它们被赋值之前

(3) 在函数体内,局部变量优先于同名的全局变量。如果你声明一个与全局变量同名的局部变量或函数参数,你实际上隐藏了全局变量

你的代码是一样的:(阅读评论

<script>
var a = 1;          //global a = 1
function b() {
    a = 10;         
    var a = 20;     //local a = 20
}
b();
alert(a);           //global a  = 1
</script>

参考:
(1)JavaScript 变量作用域:
(2) Javascript 提升的危险示例
(3)变量作用域

所以在你的代码中:

var a = 1;          //global a = 1  
function b() {
    a = 10;         
    return;
    function a() {} //local 
}
b();
alert(a);           //global a = 1  
@rochal 不,请阅读这篇文章Javascript 提升在循环中可能特别邪恶 还要检查 safari 浏览器上的代码......让我知道是的,它a=10在大多数浏览器上......实际上未定义的行为不是错误
2021-03-24 16:50:12
你在那里写了“local a Undefined”——这实际上不是真的。函数声明在父作用域的任何内容之前解析,因此在这种情况下,当您分配 a = 10 时,您已经使用值 10 覆盖了函数 a() {}。请参阅 Quentin 的回答
2021-03-25 16:50:12
@rochalvariables declared in a function are available anywhere in that function, even before they are assigned a value我也检查了它,并给出 10但根据三个教程(我给出的链接)它应该是未定义的,10 是由于未定义的结果。Quentin 根据输出回答,但我认为对于某些浏览器可能不是 10。
2021-03-30 16:50:12
阅读 Quentin 的回答中的第 4 点。此时a已经存在——它是一个函数,而不是一个未定义的。Safari 与 IE Chrome 有何不同?
2021-03-31 16:50:12
再次,在您的示例代码:a = 10; //local a Undefined不正确 a = 10; //local a is function(){} 是正确的,因为只要你检查内部函数B(value),它已经被当地的功能覆盖的(){},这样您的评论说,“当地一个未定义”无效。浏览器与它无关,它是一种语言功能。
2021-04-11 16:50:12
  1. 函数声明function a(){}首先被提升,因此在局部范围内a被创建。
  2. 如果你有两个同名的变量(一个在全局另一个在本地),局部变量总是优先于全局变量。
  3. 设置时a=10,您设置的是局部变量a,而不是全局变量

因此,全局变量的值保持不变,您会收到警报 1

当我读到你做JavaScript Scopeing 和 Hoisting的同一篇文章时,我也很困惑,因为作者从未展示过这两个开头的示例代码在编译器中的解释。

这是您提供的示例,以及页面上的第二个示例:

var a = 1;
function b() {
    function a() {} // declares 'a' as a function, which is always local
    a = 10;
    return;
}
b();
alert(a);

这是页面上的第一个示例:

var foo = 1;
function bar() {
    var foo; // a new local 'foo' variable
    if (!foo) {
        foo = 10;
    }
    alert(foo);
}
bar();

希望这可以帮助

我相信这篇文章很好地解释了提升主题2n.pl/blog/javascript-part-4
2021-03-12 16:50:12