zoukankan      html  css  js  c++  java
  • es6新增

    一、Decorator 修饰器
     
    > 用来修改类的行为

            // mixins.js
            export function mixins(...list) {
                return function (target) {
                    Object.assign(target.prototype, ...list)
                }
            }
            // main.js
            import { mixins } from './mixins'

            const Foo = {
            foo() { console.log('foo') }
            };

            @mixins(Foo)
            class MyClass {}

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

            // 用Object.assign 模拟
            const Foo = {
            foo() { console.log('foo') }
            };

            class MyClass {}

            Object.assign(MyClass.prototype, Foo);

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



    最新提案

    > 1. do表达式: 返回内部最后执行的表达式的值

            let x = do {
                let t = f();
                t * t + 1;
            };

            return (
            <nav>
                <Home />
                {
                do {
                    if (loggedIn) {
                    <LogoutButton />
                    } else {
                    <LoginButton />
                    }
                }
                }
            </nav>
            )

    > 2. throw 可用于表达式了,之前只能用于命令

            console.log(throw new Error());
            this._id = value || throw new Error("Invalid value");

    > 3. 链判断运算符

            const firstName = message?.body?.user?.firstName || 'default';
            a?.b
            // 等同于
            a == null ? undefined : a.b

            a?.[x]
            // 等同于
            a == null ? undefined : a[x]

            a?.b()
            // 等同于
            a == null ? undefined : a.b()

            a?.()
            // 等同于
            a == null ? undefined : a()


    > 4. 函数的部分执行:?是单个参数的占位符,...是多个参数的占位符

            let obj = {
            f(x, y) { return x + y; },
            };

            const g = obj.f(?, 3);
            g(1) // 4

    > 5. 管道运算符

            // 传统的写法
            exclaim(capitalize(doubleSay('hello')))
            // "Hello, hello!"

            // 管道的写法
            'hello'
            |> doubleSay
            |> capitalize
            |> exclaim
            // "Hello, hello!"

    > 6.BigInt数据类型:大于或等于2的1024次方的数值,JavaScript 无法表示,会返回Infinity;BigInt 只用来表示整数,没有位数的限制,任何位数的整数都可以精确表示。

            const a = 2172141653n;
            const b = 15346349309n;

            // BigInt 可以保持精度
            a * b // 33334444555566667777n

            // 普通整数无法保持精度
            Number(a) * Number(b) // 33334444555566670000

    > 6. BigInt对象

            BigInt(123) // 123n
            BigInt('123') // 123n
            BigInt(false) // 0n
            BigInt(true) // 1n
            // BigInt()构造函数必须有参数,而且参数必须可以正常转为数值,下面的用法都会报错。
            BigInt('123n') // SyntaxError
            BigInt('abc') // SyntaxError

    module加载规则

    > 默认情况下,浏览器是同步加载 JavaScript 脚本,即渲染引擎遇到script标签就会停下来,等到执行完脚本,再继续向下渲染。<br/>
    > 异步加载:给script加defer和async属性;渲染引擎遇到这步就会开始下载,同时页面继续渲染;defer是等到页面正常渲染完后执行。async一旦下载完脚本,浏览器就会中断渲染,立即执行此脚本

            <script src="path/to/myModule.js" defer></script>
            <script src="path/to/myModule.js" async></script>

    > ES6 将script的type属性设置为module,所以浏览器知道了这是es6模块;便执行异步加载,页面渲染完在执行,不会造成浏览器拥堵。

            <script type="module" src="./foo.js" async></script>

    > 对于ES6模块,有几点默认:

    * 1. 代码在模块作用域之中运行,而不是在全局作用域运行,模块内的变量,外部不可见。
    * 2. 脚本自动采用严格模式, 不管有没有声明use strict。
    * 3. 模块中顶层的this返回undefined,而不是指向window

    > ES6模块与commonJS模块的差异
    * 1. commonJS模块输出的是一个值得拷贝,不会被后面修改,ES6模块输出的是值得引用,可被重新赋值。
    * 2. commonJS模块是运行时加载,ES6模块是编译时输出接口。因为 CommonJS 加载的是一个对象(即module.exports属性),该对象只有在脚本运行完才会生成。而 ES6 模块不是对象,它的对外接口只是一种静态定义,在代码静态解析阶段就会生成。



    class 类

            function Point(x,y){
                this.x = x;
                this.y = y;
            }

            Point.prototype.toString = function(){
                return '(' + this.x + ',' + this.y + ')';
            }

            var p = new Point(2,4);

    > 类似 class类相当于构建了一个构造函数

            class Bar {
                doStuff(){
                    console.log('stuff');
                }

                constructor(props) {
                    super(props); //super作为一个关键字,指向原型对象时 可直接调用 super.XXX
                    //....
                }
            }

            var b = new Bar();
            b.doStuff() //stuff
            b.constructor === Bar.prototype.constructor(直接指向类的本身Bar) //这些类的方法都定义在prototype上面

    > 由于类的方法都定义在prototype上,可以通过Object.assign()向原型链上添加方法

            Object.assign(Point.prototype,{
                toString(){},
                toLower(){}
            })

    > 类的内部所有定义的方法都是不可枚举的

            Object.keys(Point.prototype) // []
            Object.getOwnPropertyNames(Point.prototype) // ['constructor','toString']

    > constructor(){}
    > constructor()方法是类的默认方法,1.new生成的实力对象的同时就自动调用constructor方法<br/>
    >2.其默认返回的是实力对象本身(this),而不是原型对象的属性

            class Self {
                constructor(x,y){
                    this.x = x; //this默认指向 类的实例,若单独提出来则指向当前运行环境,采取绑定或尖头函数
                    this.y = y;
                }

                toString(){
                    return '('+this.x + ',' + this.y + ')';
                }
            }

            var self1 = new Self(2,3);
            self1.toString(); //(2,3)
            self1.hasOwnProperty('x') //true 判断x是否为self1实力对象的自身属性
            self1.hasOwnProperty('y') //true
            self1.hasOwnProperty('toString') //false
            self1.__proto__.hasOwnProperty('toString') //true toString方法属于其原型链上的方法
            obj instanceof Self //判断obj是否为self对象的实例

    > 静态方法
    > 父类的静态方法可以被子类继承,但不会被实例继承

            class Foo{
                static classMethod(){
                    return 'hello';
                    this.propMethod(); //this指向的是类Foo,而不是实例
                }
                propMethod(){
                    console.log('hello')
                }
            }

            Foo.classMethod() //'hello' ,静态方法可以直接在Foo类上调用;其他的方法是定义在原型上不能直接调用
            Foo.propMethod() //typeError

    * 实例函数 不能继承静态方法

            var foo = new Foo();
            foo.classMethod() //typeError 静态方法不能被实例继承
            foo.propMethod(); //hello

    * 子类 可以调用父类的静态方法

            class Bar extends Foo{
                static classMethod(){
                    return super.classMethod() + ',too'
                }
            }
            Ber.classMethod() //hello,too


    > 私有属性和私有方法新提案

            class Foo {
                #a;
                #b;
                constructor(a, b) {
                this.#a = a;
                this.#b = b;
                }
                #sum() {
                return #a + #b;
                }
                printSum() {
                console.log(this.#sum());
                }
            }


    async

    >async的实现原理:就是将 Generator函数和自动执行器,包装在一个函数里

            async function myFunction() {
                try {
                await somethingThatReturnsAPromise();
                } catch (err) {
                console.log(err);
                }
            }

    * 优点:1 内置执行器。2 更好的语义。3.返回Promise。

    * 注意点:
        * 1. await命令后面的Promise对象,运行结果可能是rejected,所以最好把await命令放在try...catch代码块中。
        * 2.多个await命令后面的异步操作,如果不存在继发关系,最好让它们同时触发。

                let foo = await getFoo();
                let bar = await getBar();
                // 改写成
                let fooPromise = getFoo();
                let barPromise = getBar();
                let foo = await fooPromise;
                let bar = await barPromise;
  • 相关阅读:
    c++ 反汇编 除法优化
    python3 循环位移动
    Reverse 高校网络信息安全运维挑战赛
    2019_西湖论剑_预选赛 testre
    《C++反汇编与逆向分析技术揭秘》--算术运算和赋值
    《C++反汇编与逆向分析技术揭秘》--认识启动函数,找到用户入口
    《C++反汇编与逆向分析技术揭秘》--数据类型
    D8016 “/ZI”和“/Gy-”命令行选项不兼容
    逆向学习书籍分享
    获得PyInstaller打包exe的py源码
  • 原文地址:https://www.cnblogs.com/yxiaoqian/p/10700210.html
Copyright © 2011-2022 走看看