ES6 - Note1:块级作用域与常量

在ES6以前,ES不支持块级作用域,只有全局作用域和函数作用域,所有变量的声明都存在变量声明提升。

1.let 关键字

声明一个块级变量,只在一个代码块中有效,如果在块外面访问便会报错,如下所示:

{ let a = 1; var b = 1; } a;b;
ReferenceError: a is not defined  //没有定义

let命令非常适合循环语句,如下所示

var a = []; 
for( let j=0; j<9 ;j++){ a[j] = function(){ console.log(j); } }
a[5](); 
5

如果换成var命令,这里的输出将变成9,如下所示

var a = []; 
for( var j=0; j<9 ;j++){ a[j] = function(){ console.log(j); } }
a[5]();
9
//这里可以使用闭包来强制使程序符合预期
var a = [];
for (var j = 0; j < 9; j++) {
	a[j] = (function(i) {
		return function() {
		  console.log(i);
	}})(j);
}
a[5]();
5

let不存在变量声明提升,必须先定义后使用,且不允许重复定义,如下所示

z; let z = 1;
ReferenceError: can't access lexical declaration `z' before initialization
{ let a = 1; var a = 1; }
SyntaxError: redeclaration of let a

ES6明确规定,如果区块中存在letconst命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。

ES6的块级作用域允许多层嵌套,且互不干扰,如下所示

{ let a = 2; console.log(a); { let a= 1; console.log(a); }}
2
1

2.const关键字

使用const关键字可以声明一个常量,该常量是只读的,不可修改且也是块级作用域,类似c++的指针常量。如下所示

{ const PI = 3.1415; PI; } PI;
ReferenceError: PI is not defined

{ const PI = 3.1415; PI=3; } ;
TypeError: invalid assignment to const `PI' //不可修改

//如果常量指向一个复合对象,该常量的数据可以修改,但是地址不可以修改,和c++指针常量的概念一样
const a = {}; a.msg = "hello world"; a.msg;
"hello world"
a.msg = "hello es6!";
"hello es6!"
a
Object { msg: "hello es6!" }
a = {}
TypeError: invalid assignment to const `a'

如果想彻底冻结一个对象,可以使用ES5的Object.freeze函数,有兴趣的可以去了解Object.preventExtensions(),Object.seal(),Object.freeze(),preventExtensions可以阻止对象扩张属性,但不能阻止对现有属性的修改删除,seal可以密封对象,阻止添加新属性,但可以修改现有属性,不可删除现有属性,freeze冻结对象,不可添加属性且修改现有属性

 

posted @ 2016-06-12 14:04  SniffRose  阅读(836)  评论(1编辑  收藏  举报