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

时间:2019-06-05 17:02:01

标签: javascript scope hoisting

在函数范围内初始化变量时,除函数本身外,其他任何人都无法访问该变量。

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

下面是一些代码:


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与更改范围有关系吗?

2 个答案:

答案 0 :(得分:1)

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

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

它变成

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

答案 1 :(得分:0)

您的吊装观点不正确。当您不使用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);