JavaScript中的作用域和执行步骤

3
(function() {
            var a = 'g';
            function foo() {
                console.log(a);
                a = 7; //
            }
            console.log(foo(), a);
    }());

有人能够解释一下这段代码的逐步执行和输出吗?我得到的输出结果是'g undefined 7'。

3
没问题,步进调试器。 - Amit
我投票关闭此问题,因为可以使用调试器获得答案。 - Amit
1
你的函数 foo 没有返回任何值,这就是为什么 console.log(foo()) 返回 undefined 的原因。 - Pete
3个回答

3

您正在创建一个匿名函数并立即执行(IIFE

然后,在此作用域函数中:

  • 您声明了一个带有值ga变量
  • 您声明了一个名为foo的函数,它在父函数作用域(IIFE作用域)可见。因此,它可以看到a变量。 这个foo函数不会立即调用。
  • log语句中,执行foo
    • 记录a(值为g
    • 在IIFE作用域中更改a变量的值为7
    • foo返回空
  • 然后记录:
    • foo返回值,即undefined(没有返回值)
    • a值,在执行foo后为7

因此,您在控制台中有:

g
undefined 7

没有使用IIFE,我得到了相同的结果。好的,我明白foo()会返回"undefined",因为没有return语句。但是为什么'g'的值可以在foo()函数内部访问呢?如果我在foo()内部给'a'加上'var'关键字,结果将变为"undefined undefined g"。这意味着没有使用var关键字,变量'a'将成为全局变量。 - user3210732
foo 函数中,如果没有使用 var,那么 a 将来自于你的父级作用域(IIFE 作用域)。如果在 foo 函数中添加 var 来声明 a 变量,你将会“覆盖”来自父级作用域(IIFE 函数)的 a 变量,这被称为“遮蔽”。 在 foo 函数中以这种方式声明的 a 变量只能在 foo 函数中访问(并且可以在 foo 的假设子函数中访问)。 - codename44
好的,谢谢您的建议。我正在阅读Lan Hill的博客《高级JavaScript基础》。在阅读过程中,我尝试通过编写包含所有可能性的小函数来理解概念。 - user3210732

0

这是一个匿名自调用函数,它会在没有任何调用的情况下自动执行。

执行的结果/步骤如下:

  • 使用console.log(a);抛出g,因为最初我们有a="g"

  • 使用console.log(foo(), a);抛出undefined 7

    1. foo()将返回undefined,因为没有return语句
    2. a将返回7,因为我们执行了a=7

0
(function() {
    ...
    ...
}());

这只是声明匿名函数并调用它的一种方式

var a = 'g';
function foo() {
     console.log(a);
     a = 7; //
}
console.log(foo(), a);

在JavaScript中,您正在声明一个变量a = 'g'。如果使用关键字“var”声明变量,则该变量的作用域为函数,这意味着在该函数内(包括子函数)中,每个人都可以使用它。

然后,您正在声明一个foo函数,foo函数可以看到变量a,因为foo是在先前的函数内声明的。 console.log(a)只是打印a的值,因此它将打印'g',然后将a的值更改为7。

声明之后,您调用console.log(foo(),a),这意味着您正在执行foo并打印foo的返回值,即“undefined”,因为没有返回语句,然后打印a的值,在执行foo之后变成了7。

因此输出结果为:

g
undefined 7

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