ES6中的继承

一、基础

  在ES6之前,主要靠构造函数和原型链的灵活使用实现继承;而在ES6中引入了class(类)的概念,使得继承更加方便,也更接近传统的面向对象语言(C++,Java)中继承的实现。
  ES6中类的定义如下:
 class Point {
        constructor(x, y) {
            this.x = x;
            this.y = y;
        }
        toString() {
            return '(' + this.x + ',' + this.y + ')';
        }
    }
   //测试用例
    var point = new Point(2, 3);
    console.log(point.toString());//(2,3)
    console.log(point.hasOwnProperty('x'));//true
    console.log(point.hasOwnProperty('y'));//true
    console.log(point.hasOwnProperty('toString'));//false
    console.log(point.__proto__.hasOwnProperty('toString'));//true

  以上代码定义了一个‘类’,里边有一个constructor方法,这就是构造方法,this关键字代表实例对象。ES5中的构造函数Point,对应ES6中Point类的构造方法;
  constructor方法是类的默认方法,一个类必须有这个方法(如果没有显示定义,会默认添加constructor方法),通过new命令生成对象实例时,自动调用该方法;
  从以上的测试用例也可以看到:实例的属性除非显示定义在其本身(即:this对象上),否则都定义在原型上(这一特性和ES5一致);

二、Class的继承

  基本用法:Class之间可以通过extends关键字实现继承,这比ES5通过修改原型链实现继承,要方便很多。
  示例程序如下:
  class Point {
        constructor(x, y) {
            this.x = x;
            this.y = y;
        }

        toString() {
            return '(' + this.x + ',' + this.y + ')';
        }
    }
    //继承
    class ColorPoint extends Point {
        constructor(x, y, color) {
            super(x, y);
            this.color = color;
        }

        toString() {
            return this.color + ' ' + super.toString()
        }
    }
    var p = new ColorPoint(2, 3, 'red');
    console.log(p.toString());// red (2,3)

  以上代码中,constructor方法和toString方法中,都出现了super关键字,这里表示父类的构造函数,用来新建父类的this对象

注意:
  1、子类必须在constructor方法中调用super方法,否则新建实例会报错(因为子类没有自己的this对象,而是继承父类的this对象,然后对其进行再加工,如果不调用super方法,子类就得不到this对象);
  2、在子类的构造函数中,只有调用super之后才能用this关键字,否则会报错。原因参考1;


类的prototype属性和__proto__属性

  在ES5中,每个对象都有__proto__属性,指向构造函数的prototype属性。Class作为构造函数的语法糖,同时具有prototype属性和__proto__属性,所以存在两条继承链。
  1、子类的__proto__属性,表示构造函数的继承,总指向父类。
  2、子类的的prototype属性的__proto__属性,表示方法的继承,总指向父类的prototype属性。
  验证如下:
 class A {
    }
 class B extends A {
    }
    console.log(B.__proto__ === A);//true
    console.log(B.prototype.__proto__ === A.prototype);//true



猜你喜欢

转载自blog.csdn.net/u013910340/article/details/70879992