ES6(笔记)

ES6

字符串新增方法

  • unicode表示新增{}支持
  • String.fromCodePoint()从unicode返回对应字符
  • String.raw返回斜杠也被转义的字符串String.raw``\(标签函数形式,当作操作符放在字符串模板前即可)
  • codePointAt返回正确的unicode码点
  • repeat(n)返回新字符串表示讲原字符串重复n次
  • padStart(5,"a")padEnd()不足时填补
  • startsWith("a",5)endsWith()判断是否有某个字符串

正则扩展

  • 添加//u,能正确识别大于0xffff的unicode字符,可以通过实例的unicode属性查看是否设置
  • //y与//g功能相同,但是//y必须在匹配开始就成功匹配,作用在于让头部匹配在所有匹配中生效,通过sticky属性查看是否设置
  • //s使.可以匹配任意单个字符(好像不需要也可以)
  • 先行断言:/\d+(?=w)/ug,只匹配w前边的数字,/\d+(?!w)/ug匹配不在w前面的数字
  • 后行断言:/(?<=w)\d+/ug,只匹配w后边的数字
  • 具名组匹配
const RE_DATE = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;

const matchObj = RE_DATE.exec('1999-12-31');
const year = matchObj.groups.year; // 1999
const month = matchObj.groups.month; // 12
const day = matchObj.groups.day; // 31

replace时也可以使用相应的name

let re = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/u;

'2015-01-02'.replace(re, '$<day>/$<month>/$<year>')

数值扩展

Math扩展

  • Math.trunc()去除小数部分,返回整数部分,非数字类型调用Number
  • Math.sign()判断正负或者0
  • Math.cbrt(2)计算立方根,非数字类型使用Number转换
  • Math.hypot()返回所有参数平方和的平方根

函数的扩展

  • 函数参数具有块级作用域
  • ES6只在严格模式下启用尾调用优化
  • ES2017允许函数参数尾部有逗号
  • ES62019允许catch不携带参数

数组扩展

  • Array.from()可以传入第三个参数绑定this
  • 实例方法copyWithin(target,start,end)将从开始位置(为下标值)到结束位置的元素放到target处替换
  • indexof判断使用严格运算===,会对NaN判断错误,includes方法不会存在这个问题
  • 使用flat()方法将数组变为一维数组,传入参数指定拉平的层数,返回新数组

对象扩展

  • ES6规定,所有class类型的原型的方法都是不可枚举的
  • 对象便利顺序
    • 首先便利数值键,按升序排列
    • 再遍历字符串键,按升序排列
    • 最后便利Symbol键,按加入时间升序排列

对象新增方法

  • Object.is()严格判断是否相等,相比===对NaN、+0/-0问题做了优化
  • Object.assign(target,source)将source对象复制到target中
  • Object.fromEntries()Object.entries()的逆操作,用于将键值对数组转化为对象
Object.fromEntries([
  ['foo', 'bar'],
  ['baz', 42]
])
// { foo: "bar", baz: 42 }

其中一个用处就是将查询字符串转化为对象

Object.fromEntries(new URLSearchParams('foo=bar&baz=qux'))
// { foo: "bar", baz: "qux" }

Symbol

  • description属性查看描述
  • Symbol.for()有就返回,没有就创建。Symbol.keyFor()查询对应描述的key返回

Set和Map

  • 可以利用WeakSet存储临时对象集合(只能存储对象,结构与Set类似),垃圾回收机制不考虑WeakSet中对象的引用,没有size不能遍历
const ws=new WeakSet();

  • WeakMap只允许存储对象格式的键名(只针对键名),使用WeakMap存储的键名为弱引用,没有遍历操作,没有size

Proxy

  • Proxy.revocable返回一个可取消的实例
let {proxy, revoke} = Proxy.revocable(target, handler);

Promise对象

  • 如果已经resolve再抛出错误是无效的
  • 建议使用catch,而不直接使用第二个参数
  • ES2018引入不管finally,即不管Promise结果如何都会调用的回调
  • ES2020引入Promise.allSettled()方法,必须全部实例都完成才调用,不管成功或者失败(提案)
  • Promise.any()(只要有一个fullfiled就会变成fulfilled状态)类似与Promise.race()(只要有一个被解决或者拒绝就会结束)但是不会因为某个被rejected而结束。该方法目前是个提案

Generator

  • yield表达式如果用在另一表达式里边,必须再圆括号里面
console.log("hello" + yield 123);
  • yield如果没有通过下一步的next指定则返回值为undefined
  • generator函数遍历不返回return值
  • 错误要想被generator内部捕获至少执行一次next,不然为外部抛出错误(第一次执行next方法可以看作启动generator),generator内部布置try…catch代码块,throw抛出错误后不影响下一次遍历
  • generator实现状态机
  function clock(){
                while(true){
                    
                    yield;
                    console.log("没锁");
                    yield;
                    console.log("锁住了");
                }
            }

async函数

  • async返回promise对象且要等内部全部异步操作执行完才会执行then方法
  • async就是generator的语法糖,generator+自执行函数就是async
function spawn(gen){
        //    接受generator,返回promise
        return new Promise(function(resolve,reject){
            let genF=gen();
            function step(callback){
                let nextF;
                try{
                    nextF=callback();
                }
                catch(e){
                    reject(e);
                }
                if(nextF.done)return;
                Promise.resolve(nextF.value).then(e=>{
                    // 这样返回的还是promise
                     step(function(){
                        return genF.next(e);
                    })
                },e=>{
                    step(function(){
                        return genF.throw(e);
                    })
                })
            }
            step(function(){return genF.next(undefined)});
        })
       }

Class类

  • 类中定义的方法都是不可枚举的
  • class中的属性可以写在constructor内使用this定义,也可以直接写在类的顶层

Module

  • CommonJS运行时加载并且输出的是值的拷贝以及缓存,Module是编译时加载,可以实现动态只读引用。import会进行提升(import编译阶段执行,再代码运行之前)。
  • ComonJS可以动态加载(require到底加载哪个模块只有运行时才知道),Moudle做不到
//CommonJS的动态加载,源于CommonJS的运行时加载
const path='./' + filename;
const myModule=require(path);

  • Module顶层this不是全局(只在模块作用域有效),为undefined,CommonJS模块顶层this指向当前模块

Module的加载实现

  • JavaScript引入Module,加载类似与普通脚本添加defer,渲染完加载
  <script type="module">
            import a from './index';
            console.log(a);
    </script>

  • ES6模块加载CommonJS,Node会自动将module.exports属性当作模块的默认输出,即等同于export default xxx.
  • CommonJS的循环加载一旦出现某个模块被“循环加载”,就只输出已经执行的部分,还未执行的部分不会输出。

编程风格

  • let 取代var
  • 优先使用const
  • 字符串推荐使用单引号
  • 优先使用解构赋值
  • 单行对象不以逗号结尾,多行对象以逗号结尾
  • 对象静态化,一旦确定不可改变,如果一定要添加属性使用Object.assign()
  • 对象属性和方法尽量使用简洁表达式
  • 立即执行函数写成箭头函数形式,匿名函数使用箭头函数代替,函数配置项放在一个对象里,放在最后一个参数
  • 不在函数体内使用arguments对象获取变量
  • 如果单纯保存键值对使用Map
  • 尽量使用Class

Decorator(装饰器)–目前属于草案,需要babel支持

  • 装饰器只能用于类,不能用于函数,因为函数存在函数提升问题
  • core-devorator.js是一个三方模块,提供了几个常见的装饰器
    • @autobind使得方法中的this对象绑定原始对象
    • @readonly使属性或方法不可写
    • @override检查子类的方法,是否正确的覆盖了弗雷的同名方法
    • @deprecate (别名@deprecated)控制台显示警告,表示该方法将废除
  • traits-decorators可以实现混入,以及防止同名方法冲突、排除混入某些方法、为混入方法起别名等等。
import { traits } from 'traits-decorator';

class TFoo {
  foo() { console.log('foo') }
}

const TBar = {
  bar() { console.log('bar') }
};

@traits(TFoo, TBar)
class MyClass { }

let obj = new MyClass();
obj.foo() // foo
obj.bar() // bar


//混入实现方法
function mixin(...list){
  return function(target){
    Object.assign(target.prototype,...list);
  }
}

发布了85 篇原创文章 · 获赞 62 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_36754767/article/details/103551689
今日推荐