(第一题) ES5 构造函数与ES6 Class的区别

前面的话

这篇文章 总结了es5构造函数与 es6 Class的区别。

要点

一共总结了8点

  • Class 类中不存在变量提升
       // es5
        var bar  = new Bar(); // 可行
        function Bar() {
            this.bar = 42;
        }
    
        //es6
        const 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();
  • class的所有方法都是不可枚举的
  // es5
  function Bar() {}   
  Bar.answer = function () {};
  Bar.prototype.print = function () {};
  console.log(Object.keys(Bar));// ["answer"]
  console.log(Object.keys(Bar.prototype))// ["print"]
  // es6
  class Foo {
      constructor(){}
      static answer() {}
      print(){}
  }
  console.log(Object.keys(Foo))// []
  console.log(Object.keys(Foo.prototype));// []
  • class 必须使用new调用
    // 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
  • class 的继承有两条继承链

    一条是: 子类的__proto__ 指向父类

    另一条: 子类prototype属性的__proto__属性指向父类的prototype属性.

    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

    // es6
    class 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可以继承

  // 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]);// undefined



 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值