js中的class类

发布时间:2024年01月11日

class

ES6中之前如果我们想实现只能通过原型链和构造函数的形式,不仅难以理解步骤也十分繁琐
ES6中推出了class关键字,它可以在js中定一个类,通过new来实例化这个类的对象
需要注意的是class关键字只是一个语法糖,它的本质还是通过原型链和构造函数来实现的
class中的代码默认都是运行在strict模式下的
以下是一个简单的class关键字用法

class Person {
    name = "zhangsan";
}
let people = new Person();
let Person2 = class {
    name = "lisi";
};
let people2 = new Person2();
console.log(people, people2);

结果
可以看到类有两个定义方法,一个是类声明,即class 类名,还有一个是类表达式,类表达式可以命名也可以不命名,即 var/let/const 局部名称 = class [类名] {}
无论是类声明还是类表达式不会提升,想要使用类就必须在类定义的后面
这种定义在class中的属性被称为公有字段,如果在字段前加上#就成了私有字段

构造函数

如果我们希望在构造对象的时候传入一些参数就需要修改这个类的构造函数constructor

class Person {
    constructor(name, age, address) {
        this.name = name
        this.age = age
        this.address = address
    }
}
let people = new Person("zhangsan", 18, "wuhan")
console.log(people)

结果
构造函数的名称确定为constructor,如果一个中含有多个constructor则会抛出一个错误

方法

原型方法

能被多个实例共享的方法

class Person {
    constructor(name, age, address) {
        this.name = name
        this.age = age
        this.address = address
    }
    eating() {
        console.log(this.name + "eating...")
    }
    running() {
        console.log(this.name + " running...")
    }
}
let people = new Person("zhangsan", 18, "wuhan")
console.log(people)
people.running()
people.running()

结果

访问器方法

我们可以针对对应的属性设置getset拦截原本的修改和读取操作

class Person {
    constructor(name, age, address) {
        this._name = name
        this.age = age
        this.address = address
    }
    get name() {
        console.log("执行了读取操作")
        return this._name
    }
    set name(newName) {
        console.log("执行了设置操作")
        this._name = newName
    }
}
let people = new Person("zhangsan", 18, "wuhan")
console.log(people.name)
people.name = "lisi"

结果
注意,如果getset与属性名重复的话就会发生死循环

静态方法

静态方法则是指直接由来调用的方法,不需要实例,通过static来定义静态方法

class Person {
    constructor(name, age, address) {
        this.name = name
        this.age = age
        this.address = address
    }
    static birth(name, age, address) {
        return new Person(name, age, address)
    }
}
let people = Person.birth("wangwu", 0, "wuhan")
console.log(people)

结果

继承

ES6之前我们想要实现继承是十分麻烦且繁琐的,如何在ES6之前实现继承可以看我这篇文章
js原型与原型链
而在ES6中有了新的关键字extends可以更方便的实现继承

class Person {
    constructor(name, age, address) {
        this.name = name
        this.age = age
        this.address = address
    }
}
class Man extends Person {
}

super

super关键字可以访问父类的方法与属性
需要注意的是在constructor中调用super前不能使用this
为什么在调用super前不能访问this可以看我这篇文章
未动笔,未来可寄
super.prop可以访问父类的静态属性与方法

class Person {
    constructor(name, age, address) {
        this.name = name
        this.age = age
        this.address = address
    }
    eating() {
        console.log(this.name + "eating...")
    }
}
class Man extends Person {
    constructor(...args) {
        super(...args)
    }
    eating() {
        super.eating()
    }
}
let people = new Man("zhangsan", 18, "wuhan")
console.log(people)
people.eating()

结果

minxin

因为js继承只能继承一个,因为函数显式原型不可能有多个
如果我们想要让子类有尽可能多的复用其他类就可以使用混入
混入的原理十分简单,假如我们有ABC三个类,我们希望C能继承AB两个类,思路就是我们可以先让B继承A,再让C继承B
我们可以将这个过程封装成一个函数extends

class Person {
    constructor(name, age, address) {
        this.name = name
        this.age = age
        this.address = address
    }
    eating() {
        console.log(this.name + "eating...")
    }
}
function minix(BaseClass) {
    return class extends BaseClass {
        sleeping() {
            console.log(this.name + " sleeping...")
        }
    }
}
class Man extends minix(Person) {
    constructor(...args) {
        super(...args)
    }
    eating() {
        super.eating()
    }
}
let people = new Man("zhangsan", 18, "wuhan")
console.log(people)
people.eating()
people.sleeping()

结果

关于多态

我觉得js是有多态,多态的概念很简单:同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果
就比如a+b,如果传入的是1和2,返回的自然是3,如果传入的是"1"和"2",返回的就是"12"
这么一看js也确实符合
多态最常用的实现方式就是重载重写
重写原型链上已经实现了不必再说,关键就在于重载重载同名但参数不同的方法,但js中方法本身就可以传任意数量任意类型的参数,我们可以通过if来判断不同类型的参数执行什么操作,但这个算不算重载也很难说
我认为js作为一门弱类型的语言天然就应该是具有多态这个特性的

文章来源:https://blog.csdn.net/qq_46244470/article/details/131969002
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。