es6的class实际上是构造函数的语法糖,可是又有区别,下面来详细分析下classjavascript
先来看下class的定义的代码java
class Point{ constructor(){} toString(){} } var p = new Point() p.constructor === Point.prototype.contructor//true Object.keys(Point.prototype)//[] Object.getOwnPropertyNames(Point.prototype)//['constructor','toString']
子类必须在constructor中调用super方法,不然新建实例会报错,由于子类没有本身的this,而是继承了父类的this,这和es5中的继承不同,
由于es5中的继承是先创造子类的实例对象this,再将父类的方法添加到this上(parent.call(this)),es6中是先继承父类的实例对象this,而后再用子类的构造函数修改this。若是子类没有定义constructor,那么这个方法会被默认添加。
在子类的构造函数中,只有调用super关键字以后,才可以使用this关键字,不然会报错,由于子类实例的构建基于对父类实例的加工,只有super方法才能返回父类的实例。es6
prototype和__proto__
大多数浏览器的es5实现中,每个对象都有__proto__属性(IE8除外),指向对应的构造函数的prototype属性。class做为构造函数的语法糖,同时有prototype属性和__proto__属性,由于存在两条继承链。浏览器
若是在一个方法前加上static关键字,就表示该方法不会被实例继承,而是直接经过类调用,成为‘静态方法’。
看下代码数据结构
class Foo{ static classMethod(){} } Foo.classMethod(); class Bar extends Foo(){ static classMethod(){ return super.classMethod() } } Bar.classMethod();
上面Foo类有静态方法classMethod,只能经过Foo.classMethod调用,不可经过实例调用,不然会报错,父类的静态方法可被子类继承。函数
静态属性是指class自己的属性,即class.propname,而不是定义在实例对象(this)上的属性。this
class Foo{} Foo.prop = 1; Foo.prop //1
上面的方法能够读、写Foo类的静态属性prop,可是es6中规定,class中只有静态方法,没有静态属性es5
es6为new命令引入了new.target属性,返回new命令所做用的构造函数,若是构造函数不是经过new命令调用的,那么new.target会返回undefined,所以这个属性能够判断构造函数是如何被调用的prototype