ES6 类(class)

  JS语言的传统方法是通过构造函数,定义并生成新对象,是一种基于原型的面向对象系统。在ES6中新增加了类的概念,可以使用 class 关键字声明一个类,之后以这个类来实例化对象。
  构造函数示例
const Demo = function (a, b) {
    this.a = a;
    this.b = b;
    return this;
};

Demo.prototype = {
    constructor: Demo,
    print: function () {
        console.log(this.a + ' ' + this.b);
    }
};


const demo = new Demo('hello', 'world').print();
  class示例
class Demo {
    constructor(a, b) {
        this.a = a;
        this.b = b;
        return this;
    }

    print() {
        console.log(this.a + ' ' + this.b);
    }
};
const demo = new Demo('hello', 'world').print();
console.log(typeof demo);
  1 Demo中的constructor方法是构造方法,this关键字则代表实例对象。也就是说,ES5的构造函数Demo,对应ES6的Demo这个类的构造方法。
  2 Demo这个类除了构造方法,还定义了一个print方法。注意,定义"类"的方法的时候,前面不需要加上function这个关键字,直接把函数定义放进去了就可以了。另外,方法之间不需要逗号分隔,加了会报错。
  3 构造函数的prototype属性,在ES6的“类”上面继续存在。而且类的所有方法都定义在类的prototype属性上面。

class Point {
    string(){
        return 'aaa'
    }
}
class ColorPoint extends Point {
    constructor(color) {
        super(); // 调用父类的constructor()
        this.color = color;
    }

    toString() {
        return (this.string() )
    }
}
console.log(new ColorPoint('#000'));    //console.log(new ColorPoint(1,2,'#000'))
console.log(new ColorPoint('#000').toString());     //aaa

console.log(new ColorPoint('#000').__proto__);      //Point {constructor: function, toString: function}
console.log(ColorPoint.__proto__);      // class Point{...}
console.log(ColorPoint.prototype);      // Point {constructor: function, toString: function}
console.log(ColorPoint.__proto__.prototype);      // Object {constructor: function, string: function}

作为一个对象,子类(B)的原型(__proto__属性)是父类(A);作为一个构造函数,子类(B)的原型(prototype属性)是父类的实例。
  Object.setPrototypeOf(B.prototype, A.prototype);
  等同于
  B.prototype.__proto__ = A.prototype;

  Object.setPrototypeOf(B, A);
  等同于
  B.__proto__ = A;

super
  1、super作为函数调用时,代表父类的构造函数。ES6 要求,子类的构造函数必须执行一次super函数。
  2、super作为对象时,在普通方法中,指向父类的原型对象;在静态方法中,指向父类
  super代表了父类A的构造函数,但是返回的是子类B的实例,即super内部的this指的是B,因此super()在这里相当于A.prototype.constructor.call(this)。
class A {
    constructor() {
        this.x = 1;
    }
    print() {
        console.log(this.x);
    }
}

class B extends A {
    constructor() {
        super();
        this.x = 2;
    }
    m() {
        super.print();
    }
}

let b = new B();
b.m() // 2
class A {
    constructor() {
        this.x = 1;
    }
}

class B extends A {
    constructor() {
        super();
        this.x = 2;
        super.x = 3;
        console.log(super.x); // undefined
        console.log(this.x); // 3
    }
}

let b = new B();

  类相当于实例的原型,所有在类中定义的方法,都会被实例继承。如果在一个方法前,加上static关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态方法”。
new.target
  new是从构造函数生成实例的命令。ES6为new命令引入了一个new.target属性,(在构造函数中)返回new命令作用于的那个构造函数。如果构造函数不是通过new命令调用的,new.target会返回undefined,因此这个属性可以用来确定构造函数是怎么调用的。
  Class内部调用new.target,返回当前Class。
class Rectangle {
    constructor(length, width) {
        console.log(new.target === Rectangle);
        this.length = length;
        this.width = width;
    }
}

var obj = new Rectangle(3, 4); // 输出 true
  ps:子类继承父类时,new.target会返回子类。
class Shape {
    constructor() {
        if (new.target === Shape) {
            throw new Error('本类不能实例化');
        }
    }
}

class Rectangle extends Shape {
    constructor(length, width) {
        super();
        console.log(length+' '+width)
        // ...
    }
}

var y = new Rectangle(3, 4);  // 正确
var x = new Shape();  // 报错

 

静态方法

  函数命前声明static,就为静态方法。该方法不会被实例继承,而是直接通过类来调用。
class Person {
    constructor(name) {
        this.name = name;
    }
    static say () {
        console.log("say hi");
    }
};
Person.say();

 静态属性

  静态属性指的是Class本身的属性,即Class.propname,而不是定义在实例对象(this)上的属性。

class Foo {
}

Foo.prop = 1;
Foo.prop // 1

  新写法 

class MyClass {
    static myStaticProp = 42;

    constructor() {
        console.log(MyClass.myStaticProp); // 42
    }
}

 

实例属性

class ReactCounter extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            count: 0
        };
    }
}

  新写法

class ReactCounter extends React.Component {
    state = {
        count: 0
    };
}

 

 




  
posted @ 2017-06-06 17:41    阅读(11051)  评论(3编辑  收藏  举报