作用域(Variable space)
es6 之前只有 全局变量
和 局部变量
,没有 语句块
。
例如代码将在控制台输出 5
,因为 x
的作用域是声明了 x
的那个函数(或全局范围),而不是 if
语句块:1
2
3
4if (true) {
var x = 5; // 因为 var 声明的变量没有 语句块 的作用,所以 x 的作用域在 if 的父级,即全局
}
console.log(x); // 5
如果使用 ECMAScript 6 中的 let
声明,上述行为将发生变化。1
2
3
4if (true) {
let y = 5; // es6 新增的 let 声明的变量遵循块级作用域,作用域在 {...} 内,所以在 if 语句外获取不到。
}
console.log(y); // ReferenceError: y is not defined
变量声明提升(Variable hoisting)
由于存在变量声明提升,一个函数中所有的 var
语句应尽可能地放在接近函数顶部的地方。这将大大提升程序代码的清晰度1
2
3
4
5
6
7
8
9
10
11
12
13var myvar = "my value";
(function() {
console.log(myvar); // undefined 局部 myvar 被提升到函数顶部(JavaScript 变量感觉上是被“提升”或移到了函数或语句的顶部,然而提升后的变量将返回 undefined 值),返回 undefined 值。
var myvar = "local value"; // 覆盖全局 myvar
})();
// 也可写成这样:
(function() {
var myvar;
console.log(myvar); // undefined
myvar = "local value";
})();
es6 中 let
不会发生 变量提升1
2console.log(x); // ReferenceError
let x = 3;
全局变量((Global variables)
全局变量实际上是全局对象的属性。
- 浏览器 环境中 全局对象是
window
/self
- Node 环境中,全局对象是
globals
- Web Worker 环境中,全局对象
self
常量(Constants)
它必须被初始化为某个值 不可改,不可在运行脚本中重新声明!作用域同 let
,同一作用域中,不能使用与变量名或函数名相同的名字来命名常量!1
const prefix = '212';
const
实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指向实际数据的指针,const
只能保证这个指针是固定的(即总是指向另一个固定的地址),至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心。参考:阮一峰【ECMAScript 6 入门】