- Class 类中不存在变量提升
// es5var bar = new Bar(); // 可行function Bar() {this.bar = 42;}//es6const foo = new Foo(); // Uncaught ReferenceErrorclass Foo {constructor() {this.foo = 42;}}
- class内部会启用严格模式
// es5function Bar() {// 引用一个未声明的变量baz = 42; // it's ok}var bar = new Bar(); // es6class Foo {constructor(){// 引入一个未声明的变量fol = 42;// Uncaught ReferenceError: fol is not defined}}let foo = new Foo();
- class的所有方法都是不可枚举的
// es5function Bar() {} Bar.answer = function () {};Bar.prototype.print = function () {};console.log(Object.keys(Bar));// ["answer"]console.log(Object.keys(Bar.prototype))// ["print"]// es6class Foo {constructor(){}static answer() {}print(){}}console.log(Object.keys(Foo))// []console.log(Object.keys(Foo.prototype));// []
- class 必须使用new调用
// es5function Bar(){ }var bar = Bar();// it's ok;// es6class 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'// es6class Foo {constructor(){this.foo = 42;Foo = 'Fol'; // Uncaught TypeError: Assignment to constant variable.}}let foo = new Foo();Foo = 'Fol';// it's ok
- class 的继承有两条继承链
一条是: 子类的__proto__ 指向父类
另一条: 子类prototype属性的__proto__属性指向父类的prototype属性.
es6的子类可以通过__proto__属性找到父类,而es5的子类通过__proto__找到Function.prototype
// es5function Super() {}function Sub() {}Sub.prototype = new Super();Sub.prototype.constructor = Sub;var sub = new Sub();console.log( Sub.__proto__ === Function.prototype);// true// es6class Super{}class Sub extends Super {}let sub = new Sub();console.log( Sub.__proto__ === Super);// true
- es5 与 es6子类this的生成顺序不同。
es5的继承是先建立子类实例对象this,再调用父类的构造函数修饰子类实例(Surper.apply(this))。
es6的继承是先建立父类实例对象this,再调用子类的构造函数修饰this。即在子类的constructor方法中必须使用super(),之后才能使用this,如果不调用super方法,子类就得不到this对象。
- 正是因为this的生成顺序不同,所有es5不能继承原生的构造函数,而es6可以继承
// es5function 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// es6class arrayES6 extends Array {constructor(...args){super(...args);}}let arrayes6 = new arrayES6();arrayes6[0] = 3;console.log(arrayes6.length);// 1arrayes6.length = 0;console.log(arrayes6[0]);// undefined