ES6规范

197 阅读3分钟

ES & next

发展历史

  • 浏览器脚本:Javascript;

  • 服务器脚本: PHP / ASP / JSP;

  • ECMAScript 是一个标准,Javascript 是标准的实现;

  • ECMAScript 是Javascript 的规格;

浏览器端对于语言特性的实现有一些滞后 浏览器在用户侧升级也有一些滞后

ECMAScript / Javascript => ES6

babel

-浏览器的版本和语言本身有差异,所以我们要对语言进行编译降级

babel 6

  • ES 标准:
    • stage 0 : strawman 只是一个想法;
    • stage 1 : proposal 值得继续的提议;
    • stage 2 : draft;
    • stage 3 : candiate
    • stage 4 : finished es2024 spec 加入下一年的spec

babel-preset-stage-2,babel-preset-2016

-es标准每年都会变,babel 6的问题

babel 7

preset-env: target:[]

  • 根据用户的一些浏览器的特性,在运行时动态引入这些polyfill(垫片);bundle size最小。
  • polyfill 是一个概念:垫片,在一个只支持es5的浏览器中去运行es6

函数解析

new 一个箭头函数会怎样?

箭头函数不能作为构造函数

  • 会报错,提示:function is not a constructor;
  • babel编译时会把this转成(void 0);

哪些不能用箭头函数

  • arguments
  • yield
  • 构造函数的原型方法上

模版字符串

    const str1 = 'xiaoming';
    const str2 =  'student'
    
    console.log(`Hello 
    I am ${str1},I'm a ${str2}`)

数组和对象

数组的细节

    const funGenerator = (num) => new Array(num).map(item => params => 
    const funGenerator = (num) => Array.from(new Array(num)).map(item => params => console.log(params));
    funGenerator(10).map((func,index) => func(index));

对象的细节

    console.log(NaN === NaN); //false
    console.log(Object.is(NaN,NaN)); //true
    
    //ES next 采用了 SameValueZero() 的比较,是一个引擎内置的比较方法
    
    console.log([NaN].indexOf(NaN)) //-1
    console.log([NaN].includes(NaN)) //true SameValueZero
    
    //Object.assign深拷贝还是浅拷贝
    
    let dist = { foo: 'foo'};
    let bar = { bar: {bar:'bar'} };
    let baz = { baz:'baz' };
    
    const res = Object.assign(dist,bar,baz);
    
    bar.bar.bar = 'newbar';
    baz.baz = 'newbaz';
    
    console.log(res);//{foo:'foo',bar:{bar:'newbar'},baz:'baz'}

get / set

        class Person {
            constructor(){
                
            }
            
            _age = '';
            get age(){
                console.log(_age);
                return '18'
            }
            
            set age(val){
                this._age = val
            }
        }
        
        const str = new Person();
        str.age = 20; //20
        console.log(str.age)  //18
        

Proxy 天生的代理模式

    const stu ={
        age:20
    }
    
    const stuProxy =new Proxy(stu,{
        get: function(target, propKey,receiver){
        console.log(target, propKey)
            return Reflect.get(target, propKey,receiver)
        },
        set:function(target, propKey,value,receiver){
        console.log(target, propKey,value)
            return Reflect.set(target, propKey,value,receiver)
        },
    })

如何实现断言函数

    const assert = new Proxy({},{
        set(target,warning,value){
            if(!value){
                console.warn(warning);
            }
        }
    })
    
    const name = 'xiaoming';
    assert['is not xiaoming']=(name==='xiaohong')

receiver

     const stu ={
            age:20
        }
     const stuProxy =new Proxy(stu,{
        get: function(target, propKey,receiver){
        console.log(target, propKey)
            return receiver
        },
        set:function(target, propKey,value,receiver){
        console.log(target, propKey,value)
            return Reflect.set(target, propKey,value,receiver)
        },
    })
    //receiver 指向原始的读操作所在的那个对象,一般情况下就是Proxy实例
    console.log(stu.age) //{age:20}
    

Reflect

  1. 将Object上一些明显属于语言内部的方法放到Reflect对象上,现在Object 和Reflect 一同部署;
  2. 修改某些Object 方法的返回结果,让其更合理;

Map Set WeakMap WeakSet

  • Weak 表示作为唯一的部分,必须是一个对象;
  • Weak 是一个弱引用,不用考虑GC;

迭代器 Iterator

  • 迭代器是一个接口,为各种不同的数据提供统一的访问机制。任何数据结构只要部署了Iterator接口,就可以完成遍历操作。
    • 本质就是一个指针
    • 该接口主要供 for ... of消费

-原生具备 Iterator 的数据结构: Array Map Set String TypedArray arguments NodeList

Object.entries

    //非generator
    function entries(obj){
        let arr = [];
        for(let key of Object.keys(obj)){
            arr.push([key,obj[key]])
        }
        return arr;
    }
    
    //generator
    
    function *entries(obj){
        for(let key of Object.keys(obj)){
            yield [key,obj[key]];
        }
    }

Promise.allSettled

    function allSettled(array){
        if(!(array instanceof Arrya)){
            return reject(new Error('not array'))
        }
        return new Promise((resolve,reject)=>{
            const res = [];
            let count = 0;
            array.forEach((func,index)=>{
                Promise.resolve(func).then(value =>{
                    res[index]={
                        status:'fulfilled',value
                    }
                },(reason)=>{
                    count ++;
                    res[index]={
                        status:'rejected',reason
                    }
                }).finally(()=>{
                    ++count === array.length && resolve(res)
                })
            })
        })
    }