【问题标题】:Why variables initialized in functions can be accessed globally?为什么函数中初始化的变量可以全局访问?
【发布时间】:2019-06-05 17:02:01
【问题描述】:

当在函数范围内初始化一个变量时,除了函数本身之外,大概没有任何东西可以访问该变量。

为什么有时函数中的变量初始化可以全局访问?

下面是一些代码:


function sayHello() {
  a = 'hello';
  console.log(a);
 }
}

吊装后居然变成了这样:

function sayHello() {
  var a; // undefined
  a = 'hello';
  console.log(a);
 }
}

sayHello() // outputs 'hello'
console.log(a) // Reference error: a is not defined.

这一切都很好,直到发生这种情况:


function sayGoodbye() {
  var b = 'Goodbye';
}

吊装后居然变成了这个

function sayGoodbye() {
  var b;
  b = 'Goodbye'
}

sayGoodbye() // undefined
console.log(b) // outputs 'Goodbye'

为什么在调用sayGoodbye之后,变量b可以在全局或函数范围之外访问,而对于sayHello,存在引用错误?

console.log 是否与更改范围有关?

【问题讨论】:

  • 如果你使用一个没有定义的变量,它将被添加到全局范围中(如果你在严格模式下会抛出一个错误)
  • function sayHello() { var a; // undefined a = 'hello'; console.log(a); } } 无效代码:您有一个额外的}。这个额外的}“属于”你的 sn-p 中不存在的函数吗?
  • function sayGoodbye() { var b; b = 'Goodbye' } 不是当您不使用 var 声明变量时提升的工作方式

标签: javascript scope hoisting


【解决方案1】:

如果你在不使用严格模式的情况下分配变量而不声明它成为全局变量。

function sayGoodbye() {
  b = 'Goodbye';
}

变成了

var b;
function sayGoodbye() {
    b = 'Goodbye';
}

【讨论】:

    【解决方案2】:

    您对吊装的看法不正确。当您不声明带有var 的变量时,它会在遇到时成为全局变量。没有提升变量。所以如果你从不调用test,变量就不会在全局范围内定义。

    function test() {
      try {
        console.log("inside try", foo);
      } catch (e) {
        console.log("nope inside try: ", e.message);
      }
      console.log("test before", typeof foo)
      foo = "bar";
      console.log("test after", typeof foo)
    }
    
    console.log('outside before called: ', typeof foo);
    console.log('does not exist example: ', typeof bar);
    try {
      console.log("outside try", foo);
    } catch (e) {
      console.log("nope outside try: ", e.message);
    }
    test();
    console.log('outside after called: ', typeof foo);

    现在,如果您确实使用 var 来声明变量,那么如果您在声明之前尝试使用它,它将被提升。

    function test() {
      // var foo; <-- it is hoisted to here
      try {
        console.log("inside try", foo);
      } catch (e) {
        console.log("nope inside try: ", e.message);
      }
      console.log("test before", typeof foo)
      var foo = "bar";  // line here acts like foo="bar" since declared at top with hoisting.
      console.log("test after", typeof foo)
    }
    
    console.log('outside before called: ', typeof foo);
    console.log('does not exist example: ', typeof bar);
    try {
      console.log("outside try", foo);
    } catch (e) {
      console.log("nope outside try: ", e.message);
    }
    test();
    console.log('outside after called: ', typeof foo);

    【讨论】:

      猜你喜欢
      • 2021-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-06
      • 2014-08-23
      • 1970-01-01
      • 2021-12-10
      相关资源
      最近更新 更多