class类和构造函数相似,都是用来生成对象的
他们也有许多不同的地方:
1、类使用class关键字来定义,构造函数使用函数来定义
2、类的方法直接在类中定义,构造函数通常在原型中定义
3、类中需要定义一个constructor方法存放属性,构造函数不需要
4、类使用extends关键字即可实现继承,构造函数的继承通常是重定向原型对象
5、类的静态方法在类中使用static关键字定义,构造函数则需在外面使用点语法定义
6、类不具有函数预解析,而构造函数具有函数预解析
...
定义类
使用class关键字进行定义
constructor为构造方法,用于对象初始化,可以接收参数
class Student{
constructor(name){
this.name = name
}
}
实例化类
使用new关键字实例化,得到对象
new会执行类中的constructor方法(构造方法),将其中的属性赋予实例化对象
const obj = new A('张三')
console.log(obj) // A {name: 10}
类的方法
set、get
set和get关键字定义的方法用来修改和获取构造方法中的属性
class A{
constructor(){
this.arr = []
}
set array(item){
this.arr.push(item);
}
get array(){
return this.arr;
}
}
const obj = new A()
// 给array赋值就是执行set定义的方法,右边的值为参数
obj.array = 'haha'
// 调用array就是执行get方法
console.log(obj.array) // ['haha']
实例方法
实例方法,new出的对象.方法名()即可调用,直接定义在类中,与constructor同级
实例方法其实和构造函数一样是定义在原型上的,只不过写在类里面了
class A{
constructor(){}
say(){
console.log('haha');
}
}
const obj = new A()
obj.say() // 打印'haha'
// 类中的实例方法其实还是定义在原型上的
console.log(obj.__proto__) // {constructor: ƒ, study: ƒ}
静态方法
静态方法,不需要实例化对象就可以使用,类名.方法()即可调用
静态方法和实例方法名称可以相同
class A{
constructor(){}
static study(){
console.log('静态方法');
}
}
// 静态方法第二种定义方式
A.eat = function(){
console.log('静态方法2');
}
A.study() // '静态方法'
A.eat() // '静态方法2'
类的继承
继承:等同于将一个class类中的属性和方法复制到另一个class类中
使用extends关键字进行继承
// 父类
class A{
constructor(){
this.age = 20
}
}
// 子类
class B extends A {}
// 实例化类
const obj = new B()
console.log(obj.age) // 20
只要子类写了constructor,就必须调用super(),无论父类有没有写constructor,否则会报错
super()可以传参,参数会给到父类的constructor的形参
如果子类中的属性与父类同名,则会覆盖父类的属性
// 父类
class A{
constructor(num){
this.age = num
this.name = "张三"
}
}
// 子类
class B extends A {
constructor(){
super(10)
this.name = "李四"
}
}
// 实例化类
const obj = new B()
console.log(obj.age) // 10
console.log(obj.name) // "李四"
同名的实例方法和静态方法,子类会覆盖父类
如果需要同时执行父类的方法,需要使用super.父类方法()调用
// 父类
class A{
say(){
console.log('我是A中的实例方法say');
}
}
// 子类
class B extends A{
say(){
console.log('我是B中的实例方法say');
super.say();
}
}
// 实例化类
const obj = new B()
obj.say()
// 打印:
// '我是A中的实例方法say'
// '我是B中的实例方法say'