ECMAScript 6 笔记(2)- 块级作用域、const、顶层对象的属性

原创 乘风逐月 随笔 ES6 313阅读 2018-08-15 10:09:30 举报

阅读原文: 阮一峰:ECMAScript 6 入门

一、块级作用域

ES5只有全局作用域和函数作用域,没有块级作用域,这带来很多不合理的场景。例如计数器的循环变量泄露为全局变量。
ES6中 let 实际上为 JavaScript 增加了块级作用域。例如:

ES6 允许块级作用域的任意嵌套,如:

内层作用域可以定义与外层作用域同名的变量,如:

二、块级作用域与函数声明

ES5规定,函数只能在顶层作用域和函数作用域中声明,不能在块级作用域中声明。
ES6 引入了块级作用域,明确允许可以在块级作用域中声明函数。ES6规定,块级作用域之中,函数声明语句的行为类似于 let,在块级作用域之外不可引用。
但是为了兼容以前的代码,ES6浏览器实现了自己的行为:
a. 允许在块级作用域内声明函数。
b. 函数声明类似于 var ,即会提升到全局作用域或函数作用域的头部。
c. 函数声明还会提升到所在的块级作用域头部。

注:考虑环境差异,应该避免在块级作用域内声明函数。如果确实需要,也应该写成函数表达式,而不是函数声明语句。

三、const 命令

1.基本用法

const 声明一个只读的常量,一旦声明,常量的值就不允许修改。所有常量一旦声明就必须马上初始化,不能留到以后赋值。

对于 const 来说,只声明不赋值就会报错。

2. const 的作用域

const 的作用域与 let 命令相同,只在声明所在的块级作用域内有效。

const 命令声明的常量也是不提升,同样存在 “暂时性死区” ,只能在声明之后使用。
const 声明的常量,也与 let 一样不可以重复声明。

3.本质

const 实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。
对于简单类型的数据(数值,字符串,布尔值),值就保存在变量指向的那个内存地址,因此等于常量。
但对于复合型的数据(对象和数组),变量指向的内存地址,保存的只是一个指向实际数据的指针, const 只能保证这个指针是固定的,至于它指向的数据结构是不是可变的,就完全不能控制。因此,将一个对象声明为常量必须小心。
例如:

上例中,常量 foo 存储的只一个地址,这个地址指向一个对象。不可变的是这个地址,不能把 foo 指向另一个地址,但对象本身是可变的,所以依然可以为其添加新属性。
如果想将对象冻结,要使用 Object.freeze() 方法。

四、ES6声明变量的六种方法

var ,function, let, const, import, class

五、顶层对象的属性

1.ES5的顶层对象属性与全局变量

在浏览器中,顶层对象是指 window 对象,在 node 中值得是 global 对象。 ES5 之中,顶层对象的属性与全局对象是等价的。顶层对象的赋值与全局变量的赋值,是同一件事。如:

这样存在的问题是:
a. 没法在编译时就报出变量未声明的错误,只有运行时才知道。因为全局变量可能是顶层对象的属性创造的,而属性的创造是动态的。
b. 开发人员很容易不知不觉创造了全局变量。
c. 顶层属性到处可以读写,不利于模块化编程。

2.ES6的顶层对象属性与全局变量

ES6为了保持兼容性,规定:
a. var 命令和 function 命令声明的全局变量,依旧是顶层对象的属性。
b. let,const,class 命令声明的全局变量,不属于顶层对象的属性。
例如:

上例中 let 声明的 b 不属于顶层对象的属性,所以返回 undefined。

评论 ( 0 )
最新评论
暂无评论

赶紧努力消灭 0 回复