ES6学习之——let、const

来源:互联网 发布:怀孕b超数据怎么看 编辑:程序博客网 时间:2024/05/16 05:48

读阮一峰老师的ES6入门受益良多,好记性不如烂博客,记录学习笔记!!

一、块作用域

我们都知道,在ES5中,只有全局作用域和函数作用域,没有块级作用域,这种模式会带来一些不合理的场景。
第一种场景:内层变量可能会覆盖外层变量。

var tmp = new Date();
 
function f() {
console.log(tmp);
if (false) {
var tmp = "hello world";
}
}
 
f();

猜猜看。。。。f()会在控制台打印出什么结果,结果是。。。。。。。。。。。。。。。是undefined,有没有出乎意料。为什么?因为在函数执行的时候发生了变量提升,打印tmp时,左查询,存在,输出,但是值是undefined。
第二种比较常见的就是用来计数的循环变量泄露为全局变量。

var s = 'hello';
 
for (var i = 0; i < s.length; i++) {
console.log(s[i]);
}
 
console.log(i); // 5

而新增的let命令,让JavaScript有了快级作用域
示例:

function f1() {
let n = 5;
if (true) {
let n = 10;
}
console.log(n); // 5
}

通过let,这里就有了两个独立的作用域,内层的代码不再影响外层的代码。如果是用var定义变量的话,if的这个块级作用域是不存在的,最后n输出的会是10.
而且,块级作用域在一定情况下释放了一部分IIFE的使用情况。(这种情况就是用IIFE来构建独立的作用域,用来保护变量/也可以理解为隔离变量)

ES6规定可以在块级作用域中声明函数,但是浏览器的行为差异太大,所有,For Ninja,应该避免在块级作用域内声明函数。如果实在是要用,也应该写成函数表达式,而不是函数声明语句。

另外,ES6的块级作用域允许声明函数的规则只在使用大括号的情况下成立,如果没有使用大括号,就会报错。

二、const

const的作用域与let命令相同,只在声明所在的块级作用域内有效。
对于复合类型的变量,变量名不指向数据本身,而是指向数据所在的地址。const命令只是保证变量名指向的地址不变,并不保证该地址的数据不变。例如:

const foo = {};
foo.prop = 123;
 
foo.prop
// 123
 
foo = {}; // TypeError: "foo" is read-only

在ES5中,只有两种声明变量的方法:var命令和function命令。

ES6除了添加let和const命令,还有import命令和class命令,所有,ES6一共有6中声明变量的方法。

三、全局对象的属性

全局对象是最顶层的对象,在浏览器环境指的是window对象,在Node.js指的是global对象。ES5中,全局对象的属性与全局变量是等价的。
示例如下:

window.a = 1;
a // 1
 
a = 2;
window.a // 2

上面的变量,全局对象的属性赋值与全局变量的赋值时同一件事。

注意:Node来说,这一条只对REPL环境适用,模块环境之中,全局变量必须显示声明称global对象的属性。

未声明的全局变量,自动成为全局对象window的属性,被人们认为是JavaScript语言设计的很大的问题。
所以,在ES6中开始改变这一点。一方面规定,为了保持兼容性,var命令和function命令声明的全局变量,依旧是全局对象的属性;另一方面规定,let命令、const命令、class命令声明的全局变量,不属于全局对象的属性。这种方式,是的全局变量将逐步与全局对象的属性脱钩。

0 0