本文介绍: 类是用于创建对象模板,类只是让对象原型写法更加清晰、更像面向对象编程语法。// 构造函数// 方法say(){console.log(‘我能说话’)// 实例let zs = new Person(‘张三’, 24)// 实例let ls = new Person(‘李四’, 24)类是“特殊函数”,就像定义函数表达式函数声明一样,类语法两个组成部分:类表达式和类声明。// 类声明// 类表达式函数声明和类声明之间的一个重要区别,函数声明会提升,类声明不会。

一、什么是类

类是用于创建对象模板,类只是让对象原型写法更加清晰、更像面向对象编程的语法。

class Person {
    // 构造函数
    constructor(name, age) {
        this.name = name
        this.age = age
    }

    // 方法
    say(){
        console.log('我能说话')
    }
}
// 实例化
let zs = new Person('张三', 24)
// 实例化
let ls = new Person('李四', 24)
console.log(zs)
console.log(ls)

在这里插入图片描述

二、类的基本用法

1.定义

类是“特殊的函数”,就像定义的函数表达式和函数声明一样,类语法有两个组成部分:类表达式和类声明

// 类声明
class Point {
    constructor() {
    }
}

// 类表达式
let Point = {
    constructor(){

    }
}

函数声明和类声明之间的一个重要区别,函数声明会提升,类声明不会。需要先声明类,然后访问它。

// 构造函数变量提升
let son = new Person('zs', 24)
// Person {name: 'zs', age: 24}

// 类不会变量提升,导致引用异常
let classSon = new ClassPerson('classZs', 48)
// Uncaught ReferenceError: Cannot access 'ClassPerson' before initialization

// 构造函数
function Person(name, age) {
    this.name = name
    this.age = age
}

// 类
class ClassPerson {
    constructor(name, age) {
        this.name = name
        this.age = age
    }
}

2.constructor() 方法

一个类必须有constructor()方法,如果没有显式定义一个空的constructor()方法会被默认添加

class Point {
}

// 等同于
class Point {
  constructor() {}
}

constructor()方法什么时候执行呢?在实例化的时候自动调用该方法。constructor()方法默认返回实例对象(this)

class Point {
    constructor() {
        // 通过new命令生成对象实例时,会执行constructor方法
        console.log('我执行了')
        // 返回this是实例对象
        console.log(this)
    }
}

let p =  new Point()

类的实例化一定要使用new,否则会报错。这也是跟构造函数一个主要区别

// 构造函数
function Point1() {

}
// 可以使用new,当成普通函数执行
let p1 = Point1()

// 类
class Point {
    constructor() {
        console.log('我执行了')
        console.log(this)
    }
}
// 类不使用new会报错
// Uncaught TypeError: Class constructor Point cannot be invoked without 'new'
let p = Point()

3.静态方法属性)

类相当于实例的原型,所有在类中定义的方法(属性),都会被实例继承。如果在一个方法(属性)前,加上static关键字,就表示该方法(属性)不会被实例继承,而是直接通过类来调用

class Person {
    static personAge = 28
    constructor(name, age) {
        this.name = name
        this.age = age
    }
    static getAge(age) {
        return this.personAge + age
    }
}
let zs = new Person('zs', 28)

// 静态属性只能通过类来访问
console.log(Person.personAge) // 28

// 静态属性实例不能使用
console.log(zs.personAge) // undefined

// 静态方法只能通过类来访问
Person.getAge(28)

// 静态方法实例不能使用
// zs.getAge();
// Uncaught TypeError: zs.getAge is not a function

// 执行会报错,因为this在严格模式下是underfined
// 这个方法提取出来单独使用,this会指向该方法运行时所在的环境(由于 class 内部严格模式,所以 this 实际指向的是undefined),从而导致找不到getAge方法而报错
let getAge = Person.getAge
getAge(18)
// Uncaught TypeError: Cannot read properties of undefined (reading 'personAge')

尽管静态方法属性)不能被实例使用,但是父类静态方法可以子类继承继承那边会介绍)。

4.私有方法(属性

私有方法(属性),是只能在类的内部访问的方法和属性,外部不能访问。这也是比较常见需求,有利于代码封装。 然而私有方法(属性)的定义之前一直不是很友好,在ES2022正式为class添加私有属性,方法是在属性名之前使用#表示

class Person {
    // 私有属性
    #name = '我能说话了'
    // 私有方法
    #say() {
        // 引用私有属性
        console.log(this.#name)
    }
    // 可能这样间接调用私有方法
    indirectSay() {
        console.log(this) //Person
        this.#say()
    }
}
let p = new Person()
// p.#name
// 报错 Uncaught SyntaxError: Private field '#name' must be declared in an enclosing class
// p.#say()
// 报错 Uncaught SyntaxError: Private field '#say' must be declared in an enclosing class
// 间接调用
p.indirectSay()
// 我能说话了

当然,如果在私有方法(属性)前面加上static关键字,表示这是一个静态的私有方法(属性)。

三、继承

类可以通过extends关键字实现继承,让子类继承父类的属性和方法。

ES6 规定,子类必须在constructor()方法中调用super(),否则就会报错。这是因为子类自己的this对象,必须先通过父类构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,添加子类自己的实例属性和方法。如果不调用super()方法,子类就得不到自己的this对象。

原文地址:https://blog.csdn.net/MISS_zhang_0110/article/details/134739160

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_27064.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注