You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 05:22:18