函数无法访问全局变量的情况是什么?为什么?

时间:2017-06-30 16:27:05

标签: javascript

我遇到这种情况:



var testing = 'thing 1';

function func() {
  console.log(testing);

  var testing = 'thing 2';

  console.log(testing);
}

func();




我希望上面的代码能够记录'thing 1',然后才能'thing 2'。但是,永远不会记录'thing 1'

起初我认为将testing变量保留到其范围可能是静态函数的一些行为,因此它是undefined而不是'thing 1'

然而,考虑更多,我不确定它是否真的是一个静态功能,如果我自己的解释(最初看起来正确)是有效的。

为什么testing变量在undefinedfunc?为什么不能func访问全局变量?还有其他类似情况吗?

PS:我试图找到一个骗局,但失败了。

2 个答案:

答案 0 :(得分:6)

您无法获得thing 1的原因是因为您在testing具有本地定义的同一范围内呼叫testing。所有声明都是 "hoisted" 到其封闭范围的顶部,所以即使你写了:

var testing = 'thing 2';

在您的第一个console.log()之后,var testing被提升并作为函数中第一位代码进行处理,因此testing在本地声明,但尚未初始化(即发生在线路的原始位置。)

所以,你的代码处理如下:

var testing = 'thing 1';      // 1. Runs as soon as encountered

function func() {
  var testing;                // 3. testing is hoisted and declared, but still undefined

  console.log(testing);       // 4. undefined is logged

  testing = 'thing 2';        // 5. local `testing` is now initialized

  console.log(testing);       // 6. local `testing` is logged "thing 2"
}

func();                       // 2. func is invoked          

让多个变量具有相同的标识符(名称)完全正常(但有时令人困惑),但您必须了解的是,始终首先检查较小的范围,因此从func开始,当您要求testing时,您将获得本地版本"隐藏"该函数持续时间的全局函数。

Globals被称为全局变量,因为您可以随时访问它们。如果您需要全局版本,则始终可以将其作为全局window对象的属性进行访问:



var testing = 'thing 1';

function func() {
  console.log(testing);

  var testing = 'thing 2';

  console.log(window.testing);
}

func();




答案 1 :(得分:2)

JavaScript将所有使用var的变量声明提升到函数顶部。所以你的函数就像你这样写的那样:

function func() {
  var testing;

  console.log(testing);

  testing = 'thing 2';

  console.log(testing);
}