跳转到主内容
极星编程网:以代码为星,赴技术山海!

javascript ES6类如何定义_它是否彻底改变了继承机制?

ES6 class 是语法糖,本质仍是原型链继承,所有继承基于[[Prototype]]链,class声明编译为构造函数并自动设置prototype和constructor,extends通过Object.setPrototypeOf实现继承。 ES6
class
只是语法糖,底层仍是原型链继承 它没有改变 JavaScript 的继承机制本质——所有继承依然基于
[[Prototype]]
链。所谓“类”,只是把原本用
function
+
prototype
+
Object.setPrototypeOf
手动搭的结构,包装成更接近传统 OOP 语言的写法。 真正执行时,
class
声明会被编译为构造函数,并自动设置
prototype
和
constructor
属性;
extends
则会调用
Object.setPrototypeOf(SubClass, SuperClass)
和
Object.setPrototypeOf(SubClass.prototype, SuperClass.prototype)
。
class
内部方法默认不可枚举(比手写
prototype
更干净)
class
声明不会被提升(而函数声明会),且必须用
new
调用,否则报
TypeError: Class constructor X cannot be invoked without 'new'
静态方法和实例方法都通过
prototype
或构造函数本身挂载,没新增任何底层机制 如何正确定义
class
并实现继承? 关键在三步:定义基类、用
extends
继承、子类中必须调用
super()
(哪怕不传参)。
class Animal { constructor(name) { this.name = name; } speak() { return `${this.name} makes a sound.`; } } class Dog extends Animal { constructor(name, breed) { super(name); // ← 必须!否则报 ReferenceError this.breed = breed; } speak() { return `${this.name} barks.`; } }
不写
constructor
时,子类会自动获得默认构造函数:
constructor(...args) { super(...args); }
super()
必须在访问
this
之前调用,否则报
ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor
静态方法也能被继承:
Dog.isAnimal = true
不会覆盖从
Animal
继承来的
isAnimal
,但可通过
static get isAnimal() { return true; }
显式定义 为什么
instanceof
和
Object.getPrototypeOf
仍能准确反映真实关系? 因为
class
没有绕过原型系统,只是让原型链更“规整”。你可以用原生 API 验证它的底层结构: Eclipse导入Android或其他的JAVA项目的正确方法 WORD版 本文档主要讲述的是Eclipse导入Android或其他的JAVA项目的正确方法;希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看 下载 立即学习 “ Java免费学习笔记(深入) ”;
const dog = new Dog('Max', 'Golden'); console.log(dog instanceof Dog); // true console.log(dog instanceof Animal); // true console.log(Object.getPrototypeOf(dog) === Dog.prototype); // true console.log(Object.getPrototypeOf(Dog.prototype) === Animal.prototype); // true
Dog.prototype.__proto__
指向
Animal.prototype
(尽管不推荐直接用
__proto__
)
Dog.__proto__
指向
Animal
,这决定了静态属性/方法的继承链 如果你手动修改
Dog.prototype
(比如赋值为新对象),会断开与
Animal.prototype
的连接,
instanceof
就会失效 容易被忽略的细节:私有字段、
new.target
和装饰器兼容性 ES6
class
本身不支持私有成员,直到 ES2022 才加入
#field
语法;而
new.target
在
class
构造器中行为更严格——它能区分是否被
new
调用,这对编写可继承的工具类很关键。 私有字段
#name
是真正的私有(无法被子类访问),不是命名约定(如
_name
)
new.target
在基类构造器中指向实际被
new
的类(比如
new Dog()
时,
new.target === Dog
),可用于防止类被直接实例化 目前主流装饰器提案(如
@bound
)依赖 Babel 或 TypeScript 转译,原生
class
不支持运行时装饰,这点常被误认为是“类的限制” 真正复杂的地方在于:你得同时理解语法糖表象和原型链实质。一旦遇到奇怪的
instanceof
失败、
this
绑定异常或继承链断裂,问题几乎总出在原型操作被意外覆盖,而不是
class
本身。

相关文章