变量提升

146 阅读2分钟

不使用var声明的变量是全局变量,不推荐使用。

隐式全局变量就是隐藏的全局变量不好被发现。

  • 引擎是把函数声明整个地提升到了当前作用域的顶部
  • 同一个作用域中存在多个同名函数声明,后面出现的将会覆盖前面的函数声明
  • 函数声明的优先级最高
// 函数声明
function foo() {
    console.log('function declaration');
}

// 匿名函数表达式
var foo = function() {
    console.log('anonymous function expression');
};

// 具名函数表达式
var foo = function bar() {
    console.log('named function expression');
};
function  fn(){
    var  a  =  b  =  c  =  1;   // b和c就是隐式全局变量
}
注意:
function  fn(){
    var  a  =  b  =  c  =  1;   // b和c就是隐式全局变量(等号)
    var  a = 1;  b = 2;  c = 3;     // b和c就是隐式全局变量(分号)
    var  a = 1 ,  b = 2 ,  c = 3;    // b和c就不是隐式全局变量(逗号)
}

(function(){
   var x = y = 1;
})();
var z;

console.log(y); // 1
console.log(z); // undefined
console.log(x); // Uncaught ReferenceError: x is not defined

  • var x = y = 1 y是隐式全局变量
  • var z; 没有赋值是undefined
  • 找不到x 报错 Uncaught ReferenceError x is not defined
var a, b
(function () {
   console.log(a);  undefined
   console.log(b);  undefined
   var a = (b = 3); 赋值成功,但是b是全局变量
   console.log(a); 3
   console.log(b);  3 
})() 
console.log(a); undefined
console.log(b); 3

  • var a = (b = 3); a,b都赋值成功,但是b是全局变量
var friendName = 'World';
(function() { // 作用域里面的var和func都会变量提升
  if (typeof friendName === 'undefined') { 
    var friendName = 'Jack';
    console.log('Goodbye ' + friendName);  // 输出结果:Goodbye 
  } else {
    console.log('Hello ' + friendName);
  }
})();
  • 作用域里面的var和func都会变量提升
var foo = 3;

function hoistFunction() {
    console.log(foo); // function foo() {}

    foo = 5;
    
    console.log(foo); // 5

    function foo() {}
}

hoistFunction();
console.log(foo);     // 3

等价于

var foo = 3;

function hoistFunction() {
   var foo;

   foo = function foo() {};

   console.log(foo); // function foo() {}
   
   foo = 5;

   console.log(foo); // 5
}

hoistFunction();
console.log(foo);    // 3
  • 函数的优先权是最高的,它永远被提升至作用域最顶部,然后才是函数表达式和变量按顺序执行