es6与es5类的区别

554 阅读2分钟

ES6的class与ES5的类的区别:

  • ES6的Class 类中不存在变量提升。
  • ES6的class内部会启用严格模式(ES6类中不可引用未知变量,ES5可以)
  • ES6的class的所有方法都是不可枚举的。(输出为空)
  • ES6的class 必须使用new调用
  • ES6的class 内部无法重写类名
  • class 的继承有两条继承链

一条是: 子类的__proto__ 指向父类
另一条: 子类prototype属性的__proto__属性指向父类的prototype属性.
es6的子类可以通过__proto__属性找到父类,而es5的子类通过__proto__找到Function.prototype

  • es5 与 es6子类this的生成顺序不同。 es5的继承是先建立子类实例对象this,再调用父类的构造函数修饰子类实例(Surper.apply(this))。
    es6的继承是先建立父类实例对象this,再调用子类的构造函数修饰this。即在子类的constructor方法中必须使用super(),之后才能使用this,如果不调用super方法,子类就得不到this对象。
    正是因为this的生成顺序不同,所有es5不能继承原生的构造函数,而es6可以继承。
        //Class 类中不存在变量提升
        var bar = new Bar(); // 可行
        function Bar() {
            this.bar = 42;
        }
        //es6
        var foo = new Foo(); // Uncaught ReferenceError
        class Foo {
            constructor() {
                this.foo = 42;
            }
        }
        
        //class内部会启用严格模式
        es5
        function Bar() {
            // 引用一个未声明的变量
            baz = 42; // it's ok
        }
        var bar = new Bar();
        
        // es6
        class Foo {
            constructor() {
                // 引入一个未声明的变量
                fol = 42; // Uncaught ReferenceError: fol is not defined
            }
        }
        let foo = new Foo();

        es5
        //class的所有方法都是不可枚举的
        function Bar() {}
        Bar.answer = function() {};
        Bar.prototype.print = function() {};
        console.log(Object.keys(Bar)); // ["answer"]
        console.log(Object.keys(Bar.prototype)) // ["print"]

        //class 必须使用new调用
        // es6
        class Foo {
            constructor() {}
            static answer() {}
            print() {}
        }
        console.log(Object.keys(Foo)) // []
        console.log(Object.keys(Foo.prototype)); // []
        es5
        function Bar() {}
        var bar = Bar(); // it's ok;
        
        // es6
        class Foo {
        }
        let foo = Foo(); // Uncaught TypeError: Class constructor Foo cannot be invoked without 'new'


        //class 内部无法重写类名
        //es5
        function Bar() {
            Bar = 'Baz';
            this.bar = 42;
        }
        var bar = new Bar();
        console.log(bar); // Bar {bar: 42}
        console.log(Bar); // 'Baz'

        //es6
        class Foo {
            constructor() {
                this.foo = 42;
                Foo = 'Fol'; // Uncaught TypeError: Assignment to constant variable.
            }
        }
        let foo = new Foo();
        Foo = 'Fol'; // it's ok
        console.log(Foo); // 'Fo1'
        
        //es6的子类可以通过__proto__属性找到父类,而es5的子类通过__proto__找到Function.prototype
        //es5
        function Super() {}
        
        function Sub() {}
        Sub.prototype = new Super();
        Sub.prototype.constructor = Sub;
        var sub = new Sub();
        console.log(Sub.__proto__ === Function.prototype); // true
        console.log(Sub.prototype);
       //es6
        class Super {}
        class Sub extends Super {}
        let sub = new Sub();
        console.log(Sub.prototype);
        console.log(sub.__proto__)
        console.log(Sub.__proto__)
        console.log(Sub.__proto__ === Super); // true

        //es5
        function MyES5Array() {
            Array.apply(this, arguments);
            // 原生构造函数会忽略apply方法传入的this,即this无法绑定,先生成的子类实例,拿不到原生构造函数的内部属性。
        }
        MyES5Array.prototype = Object.create(Array.prototype, {
            constructor: {
                value: MyES5Array,
                writable: true,
                configurable: true,
                enumerable: true
            }
        })
        var arrayES5 = new MyES5Array();
        arrayES5[0] = 3;
        console.log(arrayES5.length); // 0
        arrayES5.length = 0;
        console.log(arrayES5[0]); // 3


        es6
        class arrayES6 extends Array {
            constructor(...args) {
                super(...args);
            }
        }
        let arrayes6 = new arrayES6();
        arrayes6[0] = 3;
        console.log(arrayes6.length); // 1
        arrayes6.length = 0;
        console.log(arrayes6[0]); // un