Es&next

121 阅读4分钟

发展历史

  • 浏览器脚本语言:Javascript;
  • 服务器脚本: PHP / ASP / JSP 了解内容:
  • ECMAScript 是一个标准,javaSsript 是标准的实现;
  • ECMScript 是 javaScrpt 的规格
  • ECMScript 的方言,还有JScript,ActionScript;
  • 浏览器对于语言特性的实现,有一些滞后;
  • 浏览器在用户的升级,也有一些之后; ECMAScript / javaScript -> ES6 浏览器端,商业性的产品

BABEL

  • 浏览器的版本,和语言本身有差异,所以要对语言,惊醒百安一降级

babel 6

  • ES 的标准:
    • stage0:strawman 只是一个想法
    • stage1:proposal 值得继续的提议;
    • stage2:draft
    • stage3:candidate
    • stage4:finished es2023 spec babel-preset-stage-2,babel-preset-2016
  • es 的标砖每年都会变,babel 6的问题

babel 7

preset-env: targets :[]

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

函数解析

new一个箭头函数会如何

  • 会报错 ,提示:function is not a consturctor
  • babel 编译时,会吧 this 转成(viod 0);

那些不能用 箭头函数

  • arguments
  • yield
  • 构造函数的原型方法上
    const Person = function (age, name) {
        this.age = age;
        this.name = name;
        
        const obj = { '0': 18, '1': 'zz', '2': 'teacher', '3': 'es'};
        console.log(arguments.callee)
        obj.length = 4;
        console.log(Array.prototype.slice.call(obj,2));
    }
    
    //const p = new Person(18, 'zz')
    
    //arguments / callee / caller
    
    const fibonacci = function (num) {
        if (num <= 2) return 1;
        return arguments.callee.caller(num - 1) + arguments.callee.caller(num - 2)
    }
    
    console.log(fibonacci(4))

模板字符串

    const consoleList = function (student, teacher) {
        console.log(`hello ${student}, I am ${teacher}, nice 2 meet U`)
        // console.log("hello " + student + ", I am " + teacher + ", nice 2 meet U")
    }
    
    const consoleString = function (stringTemplate, ...restVal) {
        console.log(stringTemplate.reduce((total, item, index) => total + item + (restVal[index] || ''), ''))
    }

    const stu = "my students";
    const tea = "zz";

    // consoleString(['hello', ', I am ', ', nice 2 meet U'], stu, tea);
    // 复杂的模板字符串语法
    consoleString`hello ${stu}, I am ${tea}, nice 2 meet U`
    
    const consoleList = function (student, teacher) {
        console.log(`hello ${student}, 
        I am ${teacher}, 
        nice 2 meet U`)
        // console.log("hello " + student + ", I am " + teacher + ", nice 2 meet U")
    }

    consoleList('my students', 'zz')

数组和对象

数组和对象的细节

    //数组细节
    //需要使用 Array.from 或者 .fill(0)
    const funGenerator = (num) => Array.from( new Array(num)).map(item => parems => console.log(params));
    cosnt funGenerator = (num) => new Array(num).fill(0).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))  // SameValueZero

    // JS runtime : browser / node
    

Object.assign

    //Object.assign
    //深拷贝还是浅拷贝?
    
    let dist = { foo: 'foo' };
    let bar = { bar: { bar: 'bar' }};
    let baz = { baz: 'baz'};
    
    cosnt res = object.assign(dist, bar, baz);
    
    bar.bar.bar = 'newBar';
    baz.baz = 'newBaz'
    
    //第一层是深拷贝,第二层是浅拷贝
    console.log(res) //{ foo: 'foo', bar: { bar: 'newBar'}, bar: 'baz' };
    
    console.log(res === dist); //true

get/set

    class Person {
        constructor() {
            
        }
        _age = '';
        get age() {
            console.log(`i am ${this._age} years old`)
            return '17'
        }
        set age(val) {
            console.log('it is useless to set my age, i am 17!');
            this._age = val;
        }
    }
    
    const zz = new Person();
    zz.age = '99';
    console.log('zz is', zz.age)
    

Proxy

    cosnt zz = {
        age: 99;
    }
    
    const zzProxy = new Proxy(zz, {
        get: function (target, prokey, receiver) {
            console.log('get', target, prokey)
            return Reflect.get(target, prokey, receiver)
        }
        set: function (target, prokey, value, receiver) {
            console.log('set', target, prokey, value)
        }
    })
    
    console.log(zzProxy,age = 18)

如何实现一个断言函数

    //如何实现一个断言函数
    const assert = new Proxy({}, {
        set(target, warning, value) {
            if(!value) {
                console.log(warning)
            }
        }
    })
    
    const teacher = 'zz'
    //如果断言的内容是假的,我就打印
    assert['the teacher is zz'] = (teacher === 'zxz')

receiver

    const luyi = {
        age: 35
    }
    const luyiProxy = new Proxy(luyi, {
        get: function (target, propKey, receiver) {
            return receiver;
        },
        set: function (target, propKey, value, receiver) {
            console.log("SET:", target, propKey, value)
            return Reflect.set(target, propKey, value, receiver);
        }
    })
    //receiver 指向原始的读操作所在的那个对象,一般情况下,就是 Proxy 的实例
    console.log(zzProxy.age === zz) //true

Reflect

  1. 将Object上一些明显属于语言内部的方法,放到Reflect对象上,现在Object和Reflect一同部署;
  2. 修改某些Object方法的返回结果,让其更合理;
    const teacher = {
        age: 99, name: 'zz'
    }
    
    Reflect.defineProperty(techer, 'lessions', {
        writable: false,
        enumerable: false,
        configurable: false,
        value: 'vue'
    })
    
    const res = Reflect.defineProperty(techer, 'lessions', {
        writable: true,
        enumerable: true,
        configurable: true,
        value: ['es6', 'esnext']
    })
    
    console.log(res);
    // Object.defineProperty直接报错: Cannot redefine property: lessions
    // Reflect.defineProperty 给 true or false
    

Map、Set、WeakMap、WeakSet

  1. Weak 表示作为唯一的部分,必须是一个对象;
  2. Weak 是一个弱引用,不用考虑GC
    const foos = new WeakSet();
    
    class Foo {
        constructor() {
            foos.add(this);
        }
        method() {
            if(!foos.has(this)) {
                throw new TypeError('Foo.prototype.method 只能在实例上调用')
            }else {
                console.log('using methods')
            }
        }
    }
    
    let f = new Foo();
    let b = {};
    Foo.protype.methods.call(b)

迭代器,lterator

迭代器是一个接口,为各种不同的数据提供统一的访问机制,任何数据结构只要部署了lterator接口,就可以完成遍历操作:

  1. 本质:指针
  2. 该接口主要供 for ... of 消费
  3. 原生具备 iterator 的数据结构有 Arrray Map Set String TypedArray arguments NodeList
    // let m = new Map();
    // m.set('a', 'foo');
    // m.set('b', 'bar');
    // m.set('c', 'baz');

    // let k = m.keys();

    // console.log(k.next());
    // console.log(k.next());
    // console.log(k.next());

    let arr = [1, 2, 3, 4, 5];
    let k = arr[Symbol.iterator]();

    console.log(k.next());
    console.log(k.next());
    console.log(k.next());
    console.log(k.next());
    console.log(k.next());
    console.log(k.next());

    // generator

Object.entries

    cosnt obj = {a: 11, b: 22, c:33}
    
    console.log(Object.entries(obj)); // [ [ 'a', 11 ], [ 'b', 22 ], [ 'c', 33 ] ]
    console.log(Object.keys(obj)); // [ 'a', 'b', 'c' ]
    console.log(Object.values(obj)); // [ 11, 22, 33 ]
    
    //非 generator方法
    function entries(obj) {
        let arr = [];
        for( let key of object.keys(obj)) {
            arr.push([key, obj[key]])
        }
        return arr;
    }
    // generator 的方法
    function* entires(obj) {
        for (let key of Object.keys(obj)) {
            yield [key, obj[key]];
        }
    }

    const k = entires(obj);

    console.log(k.next())
    console.log(k.next())
    console.log(k.next())
    console.log(k.next())

    for (let item of k) {
        console.log(item)
    }

promise.allSettled

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

参考网站

caniuse.com/
github.com/tc39/ecma26…
es6.ruanyifeng.com/ [es6 & esnext]
juejin.cn/post/695622… [babel]