Autumn_Ning_Blog icon indicating copy to clipboard operation
Autumn_Ning_Blog copied to clipboard

《深入理解ES6》读书笔记

Open wangning0 opened this issue 8 years ago • 2 comments
trafficstars

From 2017.8.20 To Author: winger/冉宁

wangning0 avatar Aug 20 '17 02:08 wangning0

块级作用域绑定

块级声明

块级声明用于声明在指定块的作用域之外无法访问的变量,块级作用域(词法作用域)存在于

  • 函数内部
  • 块中({ }之间的区域)

禁止重命名

假设作用域中已经存在某个标识符,此时再使用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

wangning0 avatar Aug 20 '17 02:08 wangning0

函数

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);

wangning0 avatar Aug 20 '17 03:08 wangning0