美文网首页
ES5/ES6 的继承除了写法以外还有什么区别?

ES5/ES6 的继承除了写法以外还有什么区别?

作者: 小杰66 | 来源:发表于2021-03-29 22:37 被阅读0次
    //1. class声明会提升,但不会初始化赋值,类似与let、const进入暂时性死区
    const bar = new Bar(); //it's ok
    function Bar() {
      this.bar = 42;
    }
    
    const foo = new Foo(); //ReferenceError: Cannot access 'Foo' before initialization
    class Foo {
      constructor() {
        this.foo = 42;
      }
    }
    
    //2. class 声明内部会启用严格模式
    function Bar() {
      baz = 42;
    }
    const bar = new Bar(); //it's ok
    
    class Foo {
      constructor() {
        fol = 42;
      }
    }
    const foo = new Foo(); //ReferenceError: fol is not defined
    
    //3. class的所有方法(静态方法和实例方法)都是不可枚举的
    function Bar() {
      this.bar = 42;
    }
    Bar.answer = function () {
      return 42;
    };
    Bar.prototype.print = function () {
      console.log(this.bar);
    };
    const barKeys = Object.keys(Bar);
    console.log(barKeys); //[ 'answer' ]
    const barProtoKeys = Object.keys(Bar.prototype);
    console.log(barProtoKeys); //[ 'print' ]
    
    class Foo {
      constructor() {
        this.foo = 42;
      }
      static answer() {
        return 42;
      }
      print() {
        console.log(this.foo);
      }
    }
    const fooKeys = Object.keys(Foo);
    console.log(fooKeys); //[]
    const fooProtoKeys = Object.keys(Foo.prototype);
    console.log(fooProtoKeys); //[]
    
    //4. class的所有方法(静态方法和实例方法)都没有原型对象prototype,也没有[[constructor]],不能使用new来调用
    function Bar() {
      this.bar = 42;
    }
    Bar.prototype.print = function () {
      console.log(this.bar);
    };
    const bar = new Bar();
    const barPrint = new bar.print(); //it's ok
    
    class Foo {
      constructor() {
        this.foo = 42;
      }
      print() {
        console.log(this.foo);
      }
    }
    const foo = new Foo();
    const fooPrint = new foo.print(); //TypeError: foo.print is not a constructor
    
    //5. 必须使用new调用class
    function Bar() {
      this.bar = 42;
    }
    const bar = Bar(); //it's ok
    
    class Foo {
      constructor() {
        this.foo = 42;
      }
    }
    const foo = Foo(); //TypeError: Class constructor Foo cannot be invoked without 'new'
    
    //6. class内部无法重写类名
    function Bar() {
      Bar = "Baz";
      this.bar = 42;
    }
    const bar = new Bar(); //Bar = 'baz'   bar = {bar:42}
    
    class Foo {
      constructor() {
        this.foo = 42;
        Foo = "Fol";
      }
    }
    const foo = new Foo(); //TypeError: Assignment to constant variable.
    
    //7. class子类可以通过__proto__寻到父类
    class Super {}
    class Sub extends Super {}
    const sub = new Sub();
    Sub.__proto__ === Super; //true
    
    function Super() {}
    function Sub() {}
    Sub.prototype = new Super();
    Sub.prototype.constructor = Sub;
    let sub = new Sub();
    Sub.__proto__ === Function.prototype; //true
    
    /*
    8. this生成的顺序不同。
    es5的继承先生成子类实例,再调用父类的构造函数修饰子类实例。
    es6的继承先生成父类实例,再调用子类的构造函数修饰父类实例。
    所以es6可以继承内置对象
    */
    function MyEs5Array() {
      Array.call(this, arguments);
    }
    const arrayEs5 = new MyEs5Array(); //先创建子类实例{} 所以arrayEs5为{}
    
    class MyEs6Array extends Array {}
    const arrayEs6 = new MyEs6Array(); //先创建父类实例[] 所以为arrayEs6
    

    相关文章

      网友评论

          本文标题:ES5/ES6 的继承除了写法以外还有什么区别?

          本文链接:https://www.haomeiwen.com/subject/lybjhltx.html