Autumn_Ning_Blog
Autumn_Ning_Blog copied to clipboard
《深入理解ES6》读书笔记
From 2017.8.20 To Author: winger/冉宁
块级作用域绑定
块级声明
块级声明用于声明在指定块的作用域之外无法访问的变量,块级作用域(词法作用域)存在于
- 函数内部
- 块中({ }之间的区域)
禁止重命名
假设作用域中已经存在某个标识符,此时再使用let关键字声明它就会抛出异常
var count = 10;
if(condition) {
let count = 20; // 不会报错
}
const 声明
如果const声明的是对象,不可以允许修改绑定,但是可以允许修改值
TDZ(临时死区)
与var不同,const/let声明的变量不会被提升到作用域的顶部,如果在声明之前访问这些变量,即使是相对安全的typeof操作符也会触发引用错误
if(true) {
console.log(typeof value); // ReferenceError: value is not defined
let value = 10;
}
因为此时的value还位于临界死区(TDZ),TDZ一般是人们用它来描述let/const的不提升效果
JS引擎在扫描代码发现变量生命时,遇到var声明会将它们提升至作用于顶部,遇到const/var声明时会将它们放到TDZ里,访问TDZ中的变量会触发运行时错误,只有执行过变量生命语句之后,变量才会从TDZ中移出,然后才可以正常的访问
console.log(typeof value); // undefined
if(true) {
let value = 10;
}
循环
循环中的let声明
每次循环的时候let声明都创建一个新的变量i,并将其初始化为i的当前值,所以循环内部创建的每个函数都能得到他们自己的i的副本
const funcs = [];
for(let i = 0; i < 100; i++) {
const func = function () {console.log(i)};
funcs.push(func);
}
funcs.map(item => {
item();
})
全局作用域绑定
当var被用于全局作用域时,他会创建一个新的全局变量做为全局对象,所以很有可能会覆盖一个已有的全局变量
var RegExp = 'hello';
console.log(window.RegExp); // hello
如果你在全局作用域下使用了const/let,会在全局作用域下创建一个新的绑定,而不会覆盖全局变量的属性,只会遮盖它
const RegExp = 'hello';
console.log(window.RegExp === RegExp); // false
函数
ES6中的默认参数值
在ES5中,给函数传默认参数值的方式是:
function es5_func(arg1, arg2, arg3) {
arg2 = (typeof arg2 !== 'undefined') ? arg2 : 'default1';
arg3 = (typeof arg3 !== 'undefined') ? arg3 : 'default2';
// ...
}
在ES6中,
function es6_func(arg1, arg2 = 'default1', arg3 = 'default2') {
// ...
}
默认参数值对arguments对象的影响
在ES5的非严格模式下,命名参数的改变会同步更新到arguments对象中
function mixArgs(f, s) {
console.log(f === arguments[0]); // true
console.log(s === arguments[1]); // true
f = 'change_f';
s = 'change_s';
console.log(f === arguments[0]); // true
console.log(f === arguments[0]); // true
}
mixArgs(1, 3);
在严格模式下,变现的则不同
'use strict';
function mixArgs(f, s) {
console.log(f === arguments[0]); // true
console.log(s === arguments[1]); // true
f = 'change_f';
s = 'change_s';
console.log(f === arguments[0], f, arguments[0]); // false 'change_f' 1
console.log(s === arguments[1], s, arguments[1]); // false 'change_s' 3
}
mixArgs(1, 3);
在ES6中,如果函数使用了默认参数值,无论是否在显式的严格模式下,arguments对象的行为都将与严格模式下的ES5保持一致
function mixArgs(f, s = 'B') {
console.log(arguments.length); // 1
console.log(f === arguments[0]); // true
console.log(s === arguments[1]); // false
f = 'change_f';
s = 'change_s';
console.log(f === arguments[0], f, arguments[0]); // false 'change_f' 1
console.log(s === arguments[1], s, arguments[1]); // false 'change_s' undefined
}
mixArgs(1);