JS中用new关键字创建对象实例与类继承的区别及选型建议
JavaScript中:实例添加方法 vs 类继承的区别与选择
这两种方式的作用完全不同,适用场景天差地别,下面给你拆解清楚:
一、两种方式的本质差异
1. 给单个实例添加方法(你的第一个示例)
这种方式是直接给new Animal()创建的单个对象挂载专属方法:
class Animal { constructor(name) { this.name = name; } speak() { console.log(`${this.name} makes a noise.`); } } const dog = new Animal("Golden") // 仅给dog这个实例添加bark方法 dog.bark = function(){console.log("bark")} dog.bark() // 正常执行 const cat = new Animal("Mimi") cat.bark() // 报错:cat.bark is not a function
- 这个
bark方法只属于dog这一个具体对象,其他Animal实例完全没有该方法。 - 方法直接存在于实例自身,不在原型链上,无法复用。
2. 类继承(你的第二个示例)
这种方式是创建了全新的子类Dog,继承父类Animal的所有属性和方法,同时新增子类专属的共性方法:
class Animal { constructor(name) { this.name = name; } speak() { console.log(`${this.name} makes a noise.`); } } class Dog extends Animal { // 所有Dog实例都会继承这个bark方法 bark() { console.log('Woof!'); } } const myDog = new Dog('Fido'); myDog.bark() // 正常执行 const yourDog = new Dog('Buddy'); yourDog.bark() // 同样正常执行,共享同一个bark方法
bark方法存在于Dog.prototype上,所有通过new Dog()创建的实例都会共享这个方法,节省内存。- 子类还可以扩展更多共性逻辑,比如给Dog加构造函数添加品种属性,或者重写父类的
speak方法:class Dog extends Animal { constructor(name, breed) { super(name); // 调用父类构造函数 this.breed = breed; } speak() { console.log(`${this.name} barks: Woof!`); // 重写父类方法 } }
二、核心对比点
| 维度 | 实例添加方法 | 类继承 |
|---|---|---|
| 方法作用范围 | 仅单个实例可用 | 所有子类实例共享 |
| 复用性 | 无法复用,多实例需重复添加 | 方法共享,内存高效 |
| 语义清晰度 | 无明确子类概念,语义模糊 | 明确子类关系,语义清晰 |
| 扩展性 | 仅能修改单个实例,难以扩展 | 可批量扩展子类属性/方法,易维护 |
三、该怎么选?
- 如果只是给某一个特定实例加专属功能(比如这个dog有独一无二的bark逻辑,其他动物都不需要),用实例添加方法的方式。
- 如果你需要创建多个具备相同额外功能的实例,或者后续要给这类对象统一加属性/方法,必须用类继承的方式——这也是面向对象编程中"子类"的核心意义:封装一类对象的共性特征。
内容的提问来源于stack exchange,提问作者Cagatay
相关产品推荐
相关产品推荐

