class类的特点
1、类实际上是个“特殊的函数”,就像你能够定义的函数表达式和函数声明一样,类语法有两个组成部分:类表达式和类声明。
2、函数声明和类声明之间的一个重要区别是函数声明会提升,类声明不会。
3、类必须使用new
调用,否则会报错。函数作为构造函数,进行new创建对象,此时的函数还可以不用new 作为函数使用。但是class类,不能作为函数使用,new class就是来创建对象实例的。
4、类的变量申明和具名表达式两种方式,都可以使用类。但是类的匿名表达式,由于没有类名,内部使用不了类。
5、类的原型上constructor方法和ES5中构造函数的原型上constructor属性一样。都是指向本身。
let myName = "zhu";
class Foo{
name = myName;
constructor(x,y){
this.a = x;
this.b = y;
var c = "2222";
this.getFooP = Foo.p;
}
sum(){
Foo.q = "Foo类可以用在方法中"
console.log(this.a+this.b);
}
static f1(){
return "类Foo的静态方法"
}
get prop(){
return this.a;
}
set prop(value){
this.a = value;
}
}
Foo.p = "静态属性";
Foo.f2 = function(){
return "类Foo的静态方法"
}
let foo = new Foo(1,2);
console.log(foo);
上述例子中包含了类的特点:
(1)必须通过new 类名的方式创建对象
(2)类的声明不会提升;
(3)类名作为变量名,可以直接使用在类的结构体内的方法中。不可以用在类结构体内属性上。方法在类中只是申明,当方法执行的时候,类已经申明好了,所以可以调用;但是类结构体内部的属性不可以通过类名变量进行赋值,因为此时类本身还没申明完成!
(4)constructor构造函数和ES5的构造函数一样,this上的属性和方法都会构造到实例对象上。而var c 是局部变量,且不在this上,不会构造到实例对象foo上。
(5)实例中类中的name属性,也会构造到实例对象上。constructor内的属性可以写在constructor外。由于申明类的时候,类结构体内部的属性不可以被赋值类内新增的属性和方法,所以name属性只能获取外部已经申明的值或固定值,比如“111”
(6)类结构体中的方法,都会构造到Foo.prototype原型上,且该方法是不可遍历的。
(7)类结构体中的static关键词申明的方法,是类的静态方法。即不再实例对象foo上,也不再原型Foo.prototype上。在Foo上
Foo.f1() //"类Foo的静态方法"
(8)类结构体中可以使用setter和getter来定义属性,该属性会构造在原型上,且是不可遍历的。注意setter方法必须接受参数;例子中的prop是属性,不过是以方法的形式存在,所以可以调用类结构体内的申明的方法和属性。当实例对象foo调用该属性的时候,会触发对应的getter和setter方法。
foo.prop = 10
//10
foo.a
//10
foo.prop
//10
(9)类的静态属性,可以在类申明完成后,像Foo.p 的形式去申明和赋值
Foo.p
//"静态属性"
(10)根据类的静态属性申明的方式,可以通过该方式,申明类的静态方法。像Foo.f2
注意:prop属性是在原型上,Google控制台打印因后续数据改变而受到影响。
总结:class声明类时,属性和方法存在于三个地方
(1)实例对象foo
constructor构造函数内this上的属性和方法; constructor外的属性——类结构体内声明的属性;
(2)原型Foo.prototype(属性和方法都不可遍历)
类结构体内声明的方法;类结构体内通过getter和setter声明的属性;
(3)类Foo
类结构体通过static关键词申明的方法;类外部通过Foo. 或Foo[]的形式申明的属性或方法