es6之class类(未完成)

es6之class类

  • 一、什么是类
  • 二、类的基本用法
    • 1.定义类
    • 2.constructor() 方法
    • 3.静态方法(属性)
    • 4.私有方法(属性)
  • 三、继承

一、什么是类

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

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)

es6之class类(未完成)_第1张图片

二、类的基本用法

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对象。

你可能感兴趣的:(es6,es6,前端,ecmascript)