变量

@Variable
.变量声明 - Declaring variables
.JavaScript 具有隐含的全局概念,意味着你不声明的任何变量都会成为一个全局对象属性
.JavaScript 拥有动态类型。这意味着相同的变量可用作不同的类型
.更多语句,请访问 Statements
var
.默认是全局变量
.编译时,存在变量提升,并且被初始化为 undefined;意味着你可以在声明之前访问变量,但它的值会是 undefined
.使用较少
console.log(num);//undefined
var num;
let
.块作用域 - Declares a block scope local variable
.编译时,存在变量提升,但是不会被初始化,因此在变量声明之前访问它会导致引用错误 - ReferenceError。这种情况称为暂时性死区 TDZ - Temporal Dead Zone
.应:先声明再使用
.应用较多
console.log(num);//Uncaught ReferenceError: Cannot access 'num' before initialization
let num;
const
.block-scoped local variables
.read-only
变量提升 Variable hoisting
.代码执行前,变量声明和函数声明提升到当前作用域的顶部,即:先处理变量声明和函数声明
.如果有重复声明,则后面的声明覆盖前面的声明;然后再处理其它逻辑,如赋值
.赋值不会触发提升
.更多信息,请访问 variable_hoisting预编译 pre-compiler
[] 变量提升 - msg
.原始代码
console.log(msg);
var msg = 'hi,there.'
console.log(msg);
.JavaScript 编译后,代码逻辑为
//提升
var msg;
//执行
console.log(msg);
msg = 'hi,there.'
console.log(msg);
.所以俩次log结果依次为:undefined、hi,there
[] 变量 a 和函数 foo 提升
.原始代码
var a = 1;
function foo() {
  console.log('1', a);
  var a = 3
  console.log('2', a);
}
console.log('3', a);
foo()
.JavaScript 编译后,代码逻辑为
//提升
var a;
function foo;
  var a;
//执行
a = 1
console.log('3', a); //a = 1
foo()
  console.log('1', a);//undefined - 当前作用域只声明还没有赋值
  a = 3
  console.log('2', a);//3