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 //true

继承

在ES5中,继承一般使用链继承。即新构造函数的protype等于需要继承的的构造函数的实例化,即

1
2
3
4
5
function NEWAA(){
}
NEWAA.prototype=new AA();

在ES6中使用class继承会显得清楚点。

1
class NEWA extends A{};

这时候使用extends方法让NEWA继承A的所有属性/方法,此时这两个类是一样的。

1
2
3
4
5
6
7
8
9
class NEWA extends A{
constructor(x,y,a){
super(x,y); //调用父类的constructor(x,y)
this.a=a;
}
toString(){
return this.a+super.toString(); //调用父类的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 //true
a.__proto__.constructor==A //true
function B(){};
B.prototype=new A();
var b=new B();
b.__proto__==B.prototype //true
b.__proto__.constructor==B //true
b.__proto__.__proto__==A.prototype //true
b.__proto__.__proto__.constructor==A //true

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" //刚刚set:newnewnew
a.a //gettertinytin

这里get不能传参数!。

class 静态方法

在方法前加上static即表示此方法不能被继承。

1
2
3
4
5
6
7
8
9
class A{
static fun(){
return "tinytin"
}
}
A.fun() //tinytin
var a=new A();
a.fun() //error