JS中的类--class

在 JavaScript 里,ES6 引入的 class 语法为实现面向对象编程提供了更简洁、清晰的方式。下面会详细阐述 class 里 constructor 中定义的方法和属性、外部定义的原型方法以及静态方法的区别。

1. 定义方式

constructor 内定义的方法和属性

在 class 里,constructor 是个特殊方法,当创建类的实例时会自动调用。在 constructor 中定义的方法和属性会直接关联到实例对象上。

class Animal {
    constructor(name) {
        // 定义实例属性
        this.name = name;
        // 定义实例方法
        this.speak = function() {
            console.log(`${this.name} 发出声音`);
        };
    }
}

const dog = new Animal('旺财');
console.log(dog.name); // 输出: 旺财
dog.speak(); // 输出: 旺财 发出声音

在上述代码中,name 属性和 speak 方法都是在 constructor 里定义的,它们属于 dog 这个实例。

原型方法

原型方法是定义在 class 内部但不在 constructor 中的方法,这些方法会被添加到类的原型对象上,所有实例都会共享这些方法。

class Animal {
    constructor(name) {
        this.name = name;
    }
    // 定义原型方法
    speak() {
        console.log(`${this.name} 发出声音`);
    }
}

const cat = new Animal('咪咪');
cat.speak(); // 输出: 咪咪 发出声音

这里的 speak 方法是原型方法,cat 实例可以调用它。

静态方法

静态方法使用 static 关键字定义,它属于类本身,而非类的实例。静态方法通常用于实现与类相关的工具函数或工厂方法。

class Animal {
    constructor(name) {
        this.name = name;
    }
    static create(name) {
        return new Animal(name);
    }
}

const bird = Animal.create('啾啾');
console.log(bird.name); // 输出: 啾啾

在这个例子中,create 是静态方法,通过类名 Animal 调用。

2. 访问方式

constructor 内定义的方法和属性

通过实例对象来访问 constructor 中定义的方法和属性。

class Car {
    constructor(model) {
        this.model = model;
        this.start = function() {
            console.log(`${this.model} 启动`);
        };
    }
}

const myCar = new Car('宝马');
console.log(myCar.model); // 输出: 宝马
myCar.start(); // 输出: 宝马 启动

原型方法

同样通过实例对象访问原型方法,方法里的 this 指向调用该方法的实例。

class Car {
    constructor(model) {
        this.model = model;
    }
    start() {
        console.log(`${this.model} 启动`);
    }
}

const myCar = new Car('奔驰');
myCar.start(); // 输出: 奔驰 启动

静态方法

静态方法通过类名直接访问,不能通过实例访问。

class MathUtils {
    static add(a, b) {
        return a + b;
    }
}

const result = MathUtils.add(2, 3);
console.log(result); // 输出: 5

const utils = new MathUtils();
// utils.add(2, 3); // 这会报错,实例不能调用静态方法

3. 内存占用

constructor 内定义的方法和属性

每个实例都会有自己独立的方法和属性副本,要是创建大量实例,会占用较多内存。

class Fruit {
    constructor(name) {
        this.name = name;
        this.describe = function() {
            console.log(`这是一个 ${this.name}`);
        };
    }
}

const apple = new Fruit('苹果');
const banana = new Fruit('香蕉');
// apple 和 banana 都有自己的 describe 方法副本
原型方法

所有实例共享同一个原型方法,只在内存中存在一份,所以内存占用相对较少。

class Fruit {
    constructor(name) {
        this.name = name;
    }
    describe() {
        console.log(`这是一个 ${this.name}`);
    }
}

const apple = new Fruit('苹果');
const banana = new Fruit('香蕉');
// apple 和 banana 共享同一个 describe 方法

静态方法

静态方法属于类本身,只在内存中存在一份,不随实例的创建而复制,内存占用也较少。

4. 继承特性

constructor 内定义的方法和属性

在子类继承父类时,constructor 中定义的方法和属性不会自动被子类继承,需要在子类的 constructor 里手动调用父类的 constructor 并借助 this 来访问这些方法和属性。

class Parent {
    constructor() {
        this.instanceMethod = function() {
            console.log('父类实例方法');
        };
    }
}

class Child extends Parent {
    constructor() {
        super();
    }
}

const child = new Child();
child.instanceMethod(); // 输出: 父类实例方法

原型方法

原型方法会被所有子类继承,子类实例能直接调用。

class Parent {
    prototypeMethod() {
        console.log('父类原型方法');
    }
}

class Child extends Parent {}

const child = new Child();
child.prototypeMethod(); // 输出: 父类原型方法
静态方法

静态方法也会被子类继承,可通过子类名调用。

class Parent {
    static staticMethod() {
        console.log('父类静态方法');
    }
}

class Child extends Parent {}

Child.staticMethod(); // 输出: 父类静态方法

总结

  • constructor 内定义的方法和属性:与实例紧密关联,每个实例有独立副本,通过实例访问,内存占用可能较大,继承时需手动处理。
  • 原型方法:由所有实例共享,通过实例访问,内存占用少,会自动被子类继承。
  • 静态方法:属于类本身,通过类名访问,内存占用少,也会被子类继承。

在实际开发中,可依据具体需求来选择合适的定义方式。若方法和属性与特定实例相关,可在 constructor 中定义;若多个实例需共享方法,可定义为原型方法;若方法是与类相关的工具函数,可定义为静态方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值