JS宏进阶:函数、对象和类(三)

JS本身是一种基于原型的、动态类型的脚本语言,它不像传统的面向对象编程语言(例如java、c++等)那样拥有类的概念,但是,ECMAScript 6 中引入了类的语法,使得在JavaScript中使用类变得更加直观和方便。下面是对 JavaScript 中类的详细介绍:

一、类的定义

在 ES6 中,可以使用 class 关键字来定义一个类。类的定义包括类名、构造函数 (constructor)和方法。

// 直接定义
class Person {
    // 构造函数
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }

    // 方法
    sayHello() {
        console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
    }
}


//表达式定义
const PersonClass = class {
    constructor(name) {
        this.name = name;
    }

    sayHello() {
        console.log(`Hello, ${this.name}`);
    }
};

const person2 = new PersonClass('Charlie');
person2.sayHello(); // 输出: Hello, Charlie

二、创建实例

定义一个类后,我们可以通过 new 关键字来创建类的实例,俗称:实例化。

const person1 = new Person('Alice', 30);
person1.sayHello(); // 输出: Hello, my name is Alice and I am 30 years old.

三、Getter 和 Setter

类中可以定义 getter 和 setter 方法来控制对属性的访问和修改。

class Rectangle {
    constructor(width, height) {
        this.width = width;
        this.height = height;
    }

    get area() {
        return this.width * this.height;
    }

    set area(value) {
        this.width = value[0];
        this.height = value[1];
    }
}

const rect = new Rectangle(10, 5);
console.log(rect.area); // 输出: 50
rect.area = [2, 3];
console.log(rect.area); // 输出: 6

四、类的继承与多态

在 JavaScript 中,继承和多态是面向对象编程(OOP)的两个重要概念。ES6 引入的类语法使得这些概念在 JavaScript 中的实现变得更加直观和易于理解。

1、继承

继承允许一个类(子类)继承另一个类(父类)的属性和方法。子类可以重用父类的代码,并可以添加新的属性或重写父类的方法。

1.1、extends关键字

JS中使用extends关键字,来实现类的继承。

class Animal {
    constructor(name) {
        this.name = name;
    }

    speak() {
        console.log(`${this.name} makes a sound.`);
    }
}

class Dog extends Animal {
    constructor(name, breed) {
        super(name); // 调用父类的构造函数
        this.breed = breed;
    }

    speak() {
        console.log(`${this.name} barks.`);
    }
}

const dog = new Dog('Buddy', 'Golden Retriever');
dog.speak(); // 输出: Buddy barks.

在这个例子中,Dog 类继承了 Animal 类,并重写了 speak 方法。super(name) 用于调用父类的构造函数,以初始化从父类继承的属性。

1.2、super方法

super主要用于访问父类中的属性和方法。

class Cat extends Animal {
    constructor(name, color) {
        super(name);
        this.color = color;
    }

    speak() {
        super.speak(); // 调用父类的 speak 方法
        console.log(`${this.name} is a ${this.color} cat.`);
    }
}

const cat = new Cat('Whiskers', 'black');
cat.speak();
// 输出:
// Whiskers makes a sound.
// Whiskers is a black cat.

在这个例子中,Cat 类的 speak 方法首先调用了父类 Animal 的 speak 方法,然后添加了额外的输出。

2、多态

多态允许使用统一的接口来调用不同实现的方法。在 JavaScript 中,多态通常通过方法重写和接口模拟来实现。

2.1、方法重写

方法重写是子类提供父类方法的具体实现。在上面的 Dog 和 Cat 类中,我们已经看到了方法重写的例子。每个子类都重写了 speak 方法,以提供适合其特定类型的实现。

2.2、接口模拟

虽然 JavaScript 没有正式的接口概念,但可以通过约定俗成的方法集合来模拟接口。任何实现了这些方法的类都可以被认为是实现了该接口。

class MakeSound {
    // 这不是一个真正的接口,只是一个约定
    speak() {
        throw new Error('*********************');
    }
}

class Bird extends MakeSound {
    constructor(name) {
        this.name = name;
    }

    speak() {
        console.log(`${this.name} chirps.`);
    }
}

const bird = new Bird('Tweety');
bird.speak(); // 输出: Tweety chirps.

在这个例子中,MakeSound 类可以被视为一个“接口”,因为它定义了一个 speak 方法,但没有提供具体实现。Bird 类实现了这个“接口”,提供了 speak 方法的具体实现。

3、小结

  • 继承:通过 extends 关键字,子类可以继承父类的属性和方法,并可以重写父类的方法以提供特定实现。
  • 多态:通过方法重写和接口模拟,可以使用统一的接口来调用不同实现的方法,从而实现多态性。

五、总结

ES6 引入的类语法使得 JavaScript 的面向对象编程更加直观和易于理解。尽管 JavaScript 的底层仍然是基于原型的继承机制,但类的语法提供了一个更简洁的抽象层,使得开发者可以更方便地定义和使用类。

注意点:类的声明不会被提升,必须在引用类之前声明它,否则会报错。

// let Person; // 如果尝试提前声明,然后实例化,会报错
class Person {
    constructor(name) {
        this.name = name;
    }
}

const person3 = new Person('Dave'); // 正确

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jackispy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值