《ECMAScript 6 入门》 读书笔记

一、let和const

  1. 这块相对来说还是比较基础的,有了解学习letconst定义变量的一些特点:不能重复定义、不存在变量提升、const定义常量且需要给初始值等

  2. ES6的块级作用域、暂时性死区等

二、变量的结构赋值

按照ES6的一定模式,可以从数组和对象中提取值,对变量进行赋值,这就是解构

  1. 数组解构
    let a = 1;  let b = 2;  let c = 3;
    
    let [a,b,c] = [1,2,3];
  1. 解构不成功,则变量的值就是 undefined

  2. 解构赋值允许指定默认值

    let foo[foo = true] = [];
  1. 解构不仅用于数组,还可以用于对象

  2. 对象的解构赋值是先找到同名属性,然后再付给对应的变量,真正赋值的是后者,不是前者

三、模版字符串

  1. 普通字符串
    `In JavaScript '\n' is a line-feed.`
  1. 多行字符串
`In JavaScript this is
not legal.`
  1. 字符串中嵌入变量
    var name = "Bob", time = "today";
    `Hello ${name}, how are you ${time}?`;   
    // Hello Bob, how are you today?

四、数值的扩展

  1. 学习了一些API,比如Number.isNaN()(判断是不是数字)、Number.isFinite()(判断是否有限)、Number.parseInt()(取整)、Number.isInteger()(判断是不是整数)等等

  2. 学习了Math对象的扩展,比如Math.trunc()(去除小数)、Math.sign()(判断数值正负)、Math.cbrt()(计算立方根)、Math.floor()(向下取整)等等

五、函数的扩展

  1. 函数的参数可以指定默认值

  2. 参数可以跟解构赋值默认值结合使用

  3. 默认值的参数不是尾参数,无法只省略那个参数

  4. 函数含有length属性,就是参数的个数,如果有默认值,则长度减去默认值个数,rest参数也不会计入length属性

  5. 函数的作用域、严格模式、name属性

  6. rest参数的形式为(...变量名),用来捕获多函数多余的参数,搭配的变量是一个数组,将多余的变量放到数组中

  7. 箭头函数

    • 箭头函数就是用()=> 定义函数,一个参数不需要用括号,两个或者多个就需要用圆括号把参数放里面
    • 箭头函数可以省略return
    • 返回值是对象则需要在对象外面加一个圆括号
    • 可以跟架构赋值结合使用
    • 不能new实例化,没有prototype原型、没有arguments对象
    • this指向最外层为非箭头函数的那个对象
    • 不能使用yield命令,则不能用作生成器函数
  8. 尾调优化和函数参数的尾逗号

六、数组的扩展

  1. ...扩展运算符,好比rest参数的逆运算
console.log(1,...[2,3,4,5]);
//1,2,3,4,5
  1. 可以用来合并数组,可以跟解构赋值结合使用

  2. 可以把字符串穿换成数组

  3. 任何具有Iterator接口的对象都可以使用扩展运算符转换为数组

  4. Array.from可以把一个类数组对象转变为一个真正的数组

  5. Array.of可以把一组值转变为数组

  6. 还学习了findfindIndexfillincludes

  7. entrieskeys等方法也学习了解了

七、对象的扩展

  1. 允许直接写入变量和函数作为对象的属性和方法,用于函数的返回值

  2. Object.is方法判断两个值是不是严格相等

  3. Object.assign方法用于对象的合并,还可以实现一定程度的拷贝(不可枚举的属性不能拷贝,继承属性不能拷贝)

  4. 还学习了__proto__Object.setPrototypeOf()Object.getPrototypeOf()Object.keys()Object.values()Object.entriess()等一些API

八、Set和Map数据结构

  1. Set 是一个构造函数,可以用来生成Set数据结构,Set 的成员是唯一的,则可以用来进行数组的去重

  2. 学习到了 Set 身上的一些API,比如 add (添加)、size(长度)、delete(删除)、clear(清除)、has(是否包含)等

  3. 数组的 map 和 filter 方法也是可以用在 Set 身上

  4. Map 本质上是键值对的集合,它身上也是有很多的 API ,也进行了学习了解

  5. 对一个键值进行两次赋值,则后面的会覆盖前面的

    const map = new Map();
    
    map.set(1,'a').set(1,'b');
    
    map.get(1);  //'b'
  1. 可以进行Map和数组、数组、JSON 之间的转化

九、Iterator和for...of

  1. Iterator是个遍历器,具有next方法,调用一次,指针指向他内部的下一个数据结构,不断调用,直到结束

  2. 默认的接口部署在数据结构的Symbol.iterator属性上,也就是说有这个属性,那么就是可以遍历的

  3. 扩展运算符(...)会默认调用iterator接口

  4. 具有这个接口的就是可以遍历的,就可以使用 for...of 进行遍历

  5. for...of 可以获得数组的键值,for...in 获得键名(索引)

十、Symbol

  1. Symbol 是一种新的数据类型,表示独一无二的值

  2. Symbol(),无论括号里面有没有参数,这两个值都不相等

  3. Symbol.for(),括号里参数相同,则就是同一个值,就是相等的

  4. Symbol.keyfor(),则表示一个已经登记的 Symbol 类型值的 key

十一、Promise

  1. promise是一种异步编程解决方案,里面有未来会结束的事件,有三种状态,pending(进行中)、fulfilled(成功)、rejected(失败)

  2. promise 对象是一个构造函数

var promise = new Promise(function(res,rej)){
    if(/异步操作成功/){
        resolve(val)
    }else{
        rej(reason)
    }
}
  1. promise实例生成后,可以用 then 方法来分别制定成功和失败的回调函数

  2. then方法可以实现链式调用,可以将上一步结束的值作为参数传给下一个 then

  3. promise.all()promise.race()也纳入了学习内容中

  4. 并尝试结合一些资料和教程,实现了一个自己的 promise(部分功能)

//依据 promise a+ 规范
function MyPromise(exector) {
    var self = this;
    self.state = 'pending';
    self.resolveValue = null; //存储成功的返回值用作then执行的时候的参数
    self.rejectValue = null; //存储失败的返回值用作then执行的时候的参数
    self.ResolveCallBackList = []; //存储then里面的回调函数
    self.RejectCallBackList = [];

    //成功执行
    function resolve(value) {
        if (self.state === 'pending') {
            self.state = 'fulfilled';
            self.resolveValue = value;
            self.ResolveCallBackList.forEach(function(ele) { //异步操作完成到执行这个方法的时候从数组里拿出来执行
                ele();
            })
        }
    };

    //失败执行
    function reject(reason) {
        if (self.state === 'pending') {
            self.state = 'rejected';
            self.rejectValue = reason;
            self.RejectCallBackList.forEach(function(ele) { //异步操作完成到执行这个方法的时候从数组里拿出来执行
                ele();
            })
        }
    }

    //异常处理
    try {
        exector(resolve, reject); //同步执行
    } catch (e) {
        reject(e); //接受同步执行报出的错误
    }
}

//处理各种返回值
function ResolutionReturnPromise(nextPromise, returnValue, res, rej) {
    if (returnValue instanceof MyPromise) { //返回值是一个Promise对象
        returnValue.then(function(val) {
            res(val) //给返回值是promise对象里面的成功的   下一个注册then方法(外部调用)
        }, function(reason) {
            rej(reason) //给返回值是promise对象里面的失败的   下一个注册then方法(外部调用)
        })
    } else {
        res(returnValue)
    }
}

//原型上的then方法
MyPromise.prototype.then = function(onFulfilled, onRejected) {
    var self = this;
    //链式调用空then处理
    if (!onFulfilled) { //如果then的成功处理函数不存在,即为空的then,直接return传入的值
        onFulfilled = function(val) {
            return val
        }
    }
    if (!onRejected) { //如果then的失败处理函数不存在,即为空的then,如果有错误抛出来,则传递给下一个
        onRejected = function(reason) {
            throw new Error(reason)
        }
    }
    var nextPromise = new MyPromise(function(res, rej) {

        //进行异步操作的时候这一块的状态还是pending,不会进去的
        if (self.state === 'fulfilled') {
            setTimeout(function() { //没有操作微任务的权限,则用setTimeout来模拟
                try {
                    var nextResolveValue = onFulfilled(self.resolveValue);
                    // res(nextResolveValue);
                    ResolutionReturnPromise(nextPromise, nextResolveValue, res, rej) //解决所有类型的返回值
                } catch (e) {
                    rej(e)
                }

            }, 0)
        };
        if (self.state === 'rejected') {
            setTimeout(function() {
                try {
                    var nextRejectValue = onRejected(self.rejectValue);
                    // res(nextRejectValue);
                    ResolutionReturnPromise(nextPromise, nextRejectValue, res, rej)
                } catch (e) {
                    rej(e)
                }
            }, 0)
        }



        if (self.state === 'pending') {
            setTimeout(function() {
                try {
                    self.ResolveCallBackList.push(function() {
                        var nextResolveValue = onFulfilled(self.resolveValue);
                        // res(nextResolveValue);
                        ResolutionReturnPromise(nextPromise, nextResolveValue, res, rej)
                    })
                } catch (e) {
                    rej(e)
                }
            }, 0);
            setTimeout(function() {
                try {
                    self.RejectCallBackList.push(function() {
                        var nextRejectValue = onRejected(self.rejectValue);
                        // res(nextRejectValue);
                        ResolutionReturnPromise(nextPromise, nextRejectValue, res, rej)
                    })
                } catch (e) {
                    rej(e)
                }
            }, 0)
        }
    })
    return nextPromise; //实现链式操作,把上一步then执行完返回的一个新的promise给return出来
}

十二、class

  1. class是一个类,他的数据类型是函数,本身就指向构造函数,也需要用 new 关键字来使用

  2. 里面有原型方法、静态方法、私有的属性等,不存在变量提升

  3. 学习 class 的时候要结合 js 的原型和原型链一起来学习,类的所有实例共享一个原型对象

  4. 类的方法内部有this默认指向类的实例,单独使用方法会报错

  5. 学习了解了 class 的取值函数和存执函数,函数名为变量时候要使用方括号

  6. class 的继承使用 extends 关键字

  7. super 当函数使用时候,代表父类的构造函数,子类构造函数必须执行一次 super 函数

  8. super 虽然嗲表了父类的构造函数,但是 this 指向子类

  9. super 只能在子类的构造函数中使用,在其他地方就会报错

  10. super 作为对象使用时候,在普通方法指向父类原型对象,在静态方法指向父类

  11. super 指向父类的原型对象,所以定义在父类实例上面的方法是不能通过 super 调用的

十二、Generator函数

  1. 是个生成器函数,相比于普通函数,它在 function 关键字后面加了一个 * 号,内部用的 yield 表达式

  2. 调用这个函数后,返回的是一个遍历器对象,则可以使用 next 方法,next 方法可以传值

  3. 也可以使用 for...of 循环,循环 yield 表达是后面的值,不会遍历出 return 的值

十三、async函数

  1. async就是Generator函数的语法糖

  2. 就是把Generator函数的星号替换成async,把yeild替换成await而已

  3. async函数相对于Generator函数的改进提现在如下

  • 内置执行器,也就是说,async函数的执行就跟普通函数一样就行了
  • 语义化更好,asyncawait相比于yield跟星号,更加语义化
  • 广泛的适用性, await侯敏可以使promise对象也可以是原始类型的数值
  • 返回值是promise,比Generator函数返回的Iterator更加方便,可以用then方法指定下一步的操作
  1. async有多种使用形式
    //函数声明
    async function foo(){}
    //函数表达式
    const foo = async function (){}
    //对象的方法
    let obj = {async foo(){}}
    obj.foo().then(.....)
    //class的写法
    //箭头函数
    const foo = async()=>{};
  1. async函数返回一个Promise对象

  2. 内部return返回出来的会成为then方法回调函数的参数

    async function f (){
      return 'hello world';
    }
    f().then(v=>console.log(v));
    //'hello world'
  1. await命令正常情况下await后面返回的是一个promise对象,返回对象的结果,如果不是promise对象,则直接返回那个值

  2. await后面的promise对象要是变成rejecte状态,则会被后面的catch的回调函数接收到

  3. 任何一个await后面的Promise对象变为reject状态,那么整个async函数会中断执行

    async function f() {
      await Promise.reject('出错了');
      await Promise.resolve('hello world'); // 不会执行
}
  1. 要是希望不会中断函数执行,则把它放在try catch里面,或者就是在await后面的promise对象后面加一个catch来捕获错误,await只能放在await函数内部,否则会报错

十四、prox和reflect

  1. 简单的了解了一下这部分

  2. Object.defineProperty结合对比学习了一下

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。