ES5
变量的声明(6条规则)
- 一个var可以同时声明多个变量,如“var x, y;”
- 声明的同时赋值(初始化),如“var x = 1, y = 2;”
- 声明了但是没有赋值,其值默认为undefined
- var语句可以用作for-loop和for...in的一部分
- 给一个未声明的变量赋值,JavaScript会自动用该变量名创建一个global variable。
- 但是如果要在函数内,创建的是仅在函数内部起作用的局部变量,而不是一个global变量,则必须使用var语句进行变量声明,否则被自动创建的就是global变量。
- 如果重复声明变量,那就是对该变量重新赋值。
var创建的变量作用域
- 全局变量:
- 挂载在window对象下
- 只要不是在函数里被声明的就是全局变量
- 函数变量:
- 在函数内部声明的
- 不挂载在window对象下


global & 函数 变量的优先级
在函数内,local 变量优先于global变量,同名的话,则函数内部local变量覆盖global变量。

如果要在函数内,创建的是仅在函数内部起作用的局部变量,而不是一个global变量,则必须使用var语句进行变量声明,否则被自动创建的就是global变量。
在函数内,无论哪里声明的,整个函数内部都能见,因为hoisting。但是hoisting是把变量的声明提升到了函数的开头,而不是把函数的赋值一并提升,所以是undefined。
ES5中var定义的变量没有block scope。

ES6
作用域:
- ES5:全局global scope,函数function / 局部local scope
- ES6:块级block scope
Block Scope Variable - let
let在同一个{ }括起来的block作用域下:
- let不能重复定义
- let不能提升hoisitng
- let当前作用域(通常是closure或者for-loop)有效,跳出则not defined

下面这个例子说明了第一点let不能被重复定义:

下面这个例子说明第二点let不能被提升hoisting:

下面这个例子说明第三点let当前作用域有效:
程序开始运行









for-loop执行结束后,


ES5中Closure问题,在ES5中可用IIFE立即执行函数创建匿名函数闭包来解决,在ES6中可用let来解决。

Block Scope Function













可见优先级是内部的覆盖外部的。
常量const
const在同一个{ }括起来的block作用域下:
- const / let不能重复定义
- const / let不能提升hoisitng
- const / let当前作用域(通常是closure或者for-loop)有效,跳出则not defined
- const 声明时必须赋值
- const 只读


下面这个例子说明第一点const不能重复定义或赋值和第五点const read-only:

下面这个例子说明第二点const没有提升hoisting:

下面这个例子说明第三点const当前作用域有效:

下面这个例子说明第四点const声明时必须赋值:
