Class
在ES6中,引入了Class
,可以很方便的来定义类。例如
1 2 3 4 5 6 7 8 9
| class A { constructor(x,y){ this.x=x; this.y=y; } toString(){ return this.x+this.y; } }
|
事实上ES6的class只是一个语法糖。上述代码等同于:
1 2 3 4 5 6 7
| function AA(x,y){ this.x=x; this.y=y; } AA.prototype.toString=function(){ return this.x+this.y; }
|
所以 在实例化后
1 2 3 4
| var a=new A(); var aa=new AA();
a.constructor===aa.prototype.constructor
|
继承
在ES5中,继承一般使用链继承。即新构造函数的protype等于需要继承的的构造函数的实例化,即
1 2 3 4 5
| function NEWAA(){
} NEWAA.prototype=new AA();
|
在ES6中使用class继承会显得清楚点。
这时候使用extends方法让NEWA继承A的所有属性/方法,此时这两个类是一样的。
1 2 3 4 5 6 7 8 9
| class NEWA extends A{ constructor(x,y,a){ super(x,y); this.a=a; } toString(){ return this.a+super.toString(); } }
|
在这上述这个例子里 super
可以理解成“超类”来代替父类实例,即生成一个this
对象来指向父类。因为子类没有this
对象,所以这个super方法是必须的。
并且只有调用super之后才能在方法中使用this
关键字。
当子类不添加constructor
方法时候,此时会默认添加,且会默认继承父类的所有arguments
。
1 2 3
| constructor(...args){ super(...args); }
|
个人理解原型链
简单来说即是
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| function A(){}; var a=new A();
a.__proto__==A.prototype a.__proto__.constructor==A
function B(){}; B.prototype=new A();
var b=new B();
b.__proto__==B.prototype b.__proto__.constructor==B b.__proto__.__proto__==A.prototype b.__proto__.__proto__.constructor==A
|
class 的 getter 和setter
同 ES5的一样(vue的响应式原理即使用这个)
1 2 3 4 5 6 7 8
| Object.defineProperty(obj,key,{ get:function(){
}, set:function(){
} })
|
ES6 class的getter和setter更加方便点。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| class A{ constructor(x){ this.x=x; } get a(){ return "getter"+this.x; } set a(value){ console.log("刚刚set:"+value); } } var a=new A("tinytin"); a.a="newnewnew" a.a
|
这里get不能传参数!。
class 静态方法
在方法前加上static
即表示此方法不能被继承。
1 2 3 4 5 6 7 8 9
| class A{ static fun(){ return "tinytin" } } A.fun()
var a=new A(); a.fun()
|