繁体   English   中英

Javascript-可变提升

[英]Javascript- Variable Hoisting

这是一个简单的片段,我只是不明白的东西。

下面的代码输出12,我理解,因为var foo = 12; 替换先前的变量声明。

<script>
var foo = 1;
function bar(){
  if (!foo) {
    var foo = 12;
  }
  alert(foo);
}
bar();
</script>

在下面的代码中,它会发出警报1 ,这意味着在函数内部可以访问在函数外部声明的变量。

  <script>
    var foo = 1;
    function bar(){
      alert(foo);
    }
    bar();
    </script>

但是,在下面的代码中,为什么它会提示undefined? 我想,它会警告1 ,我只是将之前声明的变量分配给新的变量。

  <script>
    var foo = 1;
    function bar(){
      if (!foo) {
        var foo = foo;
      }
      alert(foo);
    }
    bar();
    </script>

变量声明被推送到函数的开头。

因此实际上发生了以下情况:

function bar(){
      var foo;
      if (!foo) {
        foo = foo;
      }
      alert(foo);
}

因此,您需要将其更改为使用window.foo以便您引用全局属性而不是函数的属性:

var foo = 1;
function bar(){
   var foo;
   if (!window.foo) {
      foo = window.foo;
   }
   alert(foo);
}
bar();

吊装有点棘手。 函数声明随函数赋值一起提升,但变量声明在没有变量赋值的情况下被提升。 所以代码的执行顺序实际上是:

var foo;
var bar = function bar(){
  var foo; // undefined
  if (!foo) { // true
    foo = foo; // foo = undefined
  }
  alert(foo);
}
foo = 1;
bar();

如果要引用全局变量foo ,可以使用window.foo ,或者更好,只需使用不同的变量名:

var foo = 1;
function bar(){
  var baz =  foo;
  alert(baz);
}
bar();

下面的代码输出12,我理解,因为var foo = 12; 替换先前的变量声明。

var foo = 1;
function bar(){
  if (!foo) {
    var foo = 12;
  }
  alert(foo);
}
bar();

你是对的,因为局部变量覆盖了全局变量。

在下面的代码中,它会发出警报1,这意味着在函数内部可以访问在函数外部声明的变量。

var foo = 1;
function bar(){
  alert(foo);
}
bar();

你是对的。 foo在全局范围内声明,因此可以从任何地方访问。

但是,在下面的代码中,为什么它会提示undefined? 我想,它会警告1,我只是将之前声明的变量分配给新的变量。

var foo = 1;
function bar(){
  if (!foo) {
    var foo = foo;
  }
  alert(foo);
}
bar();

这有点不同。 您正在声明一个全局变量和一个具有相同名称的本地变量。 当您的JavaScript程序执行进入一个新函数时,函数中任何位置声明的所有变量都会被移动(或提升或提升)到函数的顶部。

另一个例子:

 var a = 123; function f() { var a; // same as: var a = undefined; alert(a); // undefined a = 1; alert(a); // 1 } f(); 

在javascript中,直到ES5规范,范围仅在函数体方面实现。 块范围的概念不存在( 实际上,将使用let关键字在下一个javascript中实现 )。

所以,如果你声明一个变量var something; 在函数体之外,它将是全局的(在浏览器全局范围内是window对象的范围)。

  1. 全局变量

 var something = 'Hi Man'; /** * this is equal to: **/ window.something = 'Hi Man'; 

如果您的代码不以严格模式运行,则还有另一种声明全局变量的方法:省略var关键字。 省略var关键字时,变量属于(或移动)到全局范围。

  1. 例:

 something = 'Hi Man'; /** * this is equal to: **/ function someFunction() { something = 'Hi Man'; } 

局部变量

因为块范围的不存在,声明局部变量的唯一方法是在函数体中定义它。

 var something = 'Hi Man'; //global console.log('globalVariable', something); function someFunction() { var something = 'Hi Woman'; console.log('localVariable', something); /** * defining variable that doesn't exists in global scope **/ var localSomething = 'Hi People'; console.log('another local variable', localSomething); } someFunction(); console.log('globalVariable after function execution', something); try { console.log('try to access a local variable from global scope', localSomething); } catch(e) { console.error(e); } 

正如您在此示例中所看到的,局部变量不在其范围之外。 这意味着另一件事......如果使用var关键字在两个不同的范围中声明相同的变量,您将获得两个不同的变量,而不是覆盖父范围中定义的相同变量(名称)。

如果要在子范围中 “覆盖”相同的变量,则必须在不使用var关键字的情况下使用它。 由于范围链,如果局部范围中不存在变量,则将在其父范围内搜索。

 function someFunction() { something = 'Hi Woman'; } var something = 'Hi Man'; console.log(1, 'something is', something); someFunction(); console.log(1, 'something is', something); 

最后一件事,可变升降机。

正如我在下面所写,目前,没有任何方法可以在代码的某些方面声明变量。 它始终在范围的开头声明。

 function someFunction() { // doing something // doing something else var something = 'Hi Man'; } /** * Probably you expect that the something variable will be defined after the 'doing * something else' task, but, as javascript works, it will be defined on top of it scope. * So, the below snippet is equal to: **/ function someFunction1() { var something; // doing something // doing something else something = 'Hi Man'; } /** * You can try these following examples: * * In the someFunction2 we try to access on a non-defined variable and this throws an * error. * * In the someFunction3, instead, we don't get any error because the variable that we expect to define later will be hoisted and defined at the top, so, the log is a simple undefined log. **/ function someFunction2() { console.log(something); }; function someFunction3() { console.log('before declaration', something); var something = 'Hi Man'; console.log('after declaration', something); } 

发生这种情况是因为在javascript中有两个不同的变量声明步骤:

  • 定义
  • 初始化

function3示例如下:

 function3Explained() { var something; // define it as undefined, this is the same as doing var something = undefined; // doing something; // doing something else; something = 'Hi Man'; } 

恕我直言,它与功能声明和吊装没有任何关系,

使用var inside函数声明var,你在函数的隔离范围中创建一个变量,这就是你未定义的原因。

 var foo = 1;
 function funcOne() {
     var foo = foo;
     alert('foo is ' + foo);
 };
 funcOne();

 var bau = 1;
 function funcTwo() {
     bau = bau;
     alert('bau is ' + bau);
 };
 funcTwo();

小提琴

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM