函数作用域中的行为令人困惑

3

我刚开始学习 JavaScript,练习作用域时尝试了以下代码:

var il = "inner";
var o ="outer";

var of = function(){

  console.log(o + " " + il);

  o = "baher";
  var il = "ander";
  console.log(o + " " + il);

  var lf = function(){
    console.log(o  + " " +il);
    o = "mazed baher";
    var il = "mazed ander";
    console.log(o + " " +il);
  };

  console.log(o + " " +il);

};

of();
console.log(o + " " + il);

////////////////////////////////////// 它的输出非常惊人

"outer undefined" 
"baher ander" 
"baher ander" 
"baher inner" 

我无法理解这段代码。我使用了console.log 6次,但只得到了4个输出。而且为什么第一个log中的"il"未定义?


你的两个 console.log 在一个从未被调用的函数中。 - Alexey Ten
1
由于变量提升,il未定义。 - Alexey Ten
你很困惑! - Faisal Ashfaq
4个回答

3

它只输出了四次

你的两个console.log语句都在未被调用的lf函数内部。

为什么第一次 "il" 的输出是 undefined?

var语句会被提升。

var of = function(){
    console.log(o + " " + il);
    o = "baher";
    var il = "ander";

这一段最后一行在函数范围内创建了一个本地变量il。由于它是被提升的,所以这个变量会在函数进入时立即创建。

第二行读取了该本地变量的值,但它还没有被赋值,因此它是undefined

第三行然后给它赋了一个值。


2

首先,新的作用域仅适用于函数。像whileif这样的条件块不会创建新的作用域。

其次,在JS中,变量定义总是会被提升到作用域的顶部。因此,当您通过var创建变量时,实际上它会被定义在作用域的顶部,并初始化为undefined

console.log(o + " " + il);
o = "baher";
var il = "ander";

在给定的示例中,本地变量il将覆盖外部作用域中的il。因此,它将如下所示:
var il; // undefined
console.log(o + " " + il);
o = "baher"; // outer scope
il = "ander"; // inner scope

0

il 未定义的原因是它在函数 of 内被重新声明,而声明被提升到函数顶部(但不包括赋值)。请参见下面的代码以了解我的意思。我还展示了其他变量声明如何被提升。

两个日志语句未运行的原因是从未调用函数 lf

var il = undefined;
var o = undefined;
var of = undefined;

il = "inner";
o ="outer";

of = function(){
    // il gets hoisted
    var il = undefined;
    var lf = undefined;

    console.log(o + " " + il);

    o = "baher";
    il = "ander";
    console.log(o + " " + il);

    // this function is never called
    lf = function(){
        var il = undefined;
        console.log(o  + " " +il);
        o = "mazed baher";
        il = "mazed ander";
        console.log(o + " " +il);
    };

    console.log(o + " " +il);

};

of();
console.log(o + " " + il);

0
代码中的`var il = "ander";`位于函数块内部,所以在调用它之前,代码对其进行了日志记录,因此它是未定义的。 你的嵌套函数中发生了相同的事情,但在此之前是嵌套函数,因此它获取了父函数中定义的ander的值。

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