
在javascript中,es6的class语法提供了一种更清晰、更面向对象的方式来定义构造函数和它们相关的原型方法。然而,这仅仅是现有原型继承模式之上的一层抽象(或称“语法糖”)。
考虑一个典型的类定义,其中包含一个方法:
class Foo {
barMethod() {
console.log("This is a prototype method.");
}
}
// 实际上,这大致等同于:
// function Foo() {}
// Foo.prototype.barMethod = function() { console.log("This is a prototype method."); };当我们创建一个Foo的实例时,barMethod可以通过原型链被访问到:
const instance1 = new Foo(); instance1.barMethod(); // 输出: This is a prototype method. console.log(Foo.prototype.barMethod === instance1.barMethod); // 输出: true
这表明barMethod是定义在Foo.prototype上的,所有Foo的实例都共享同一个barMethod函数。
然而,当我们在类中声明一个“公共实例字段”(Public Instance Field)时,其行为与原型方法截然不同。公共实例字段允许我们在类定义内部直接声明并初始化实例属性,而无需在constructor中显式使用this。
立即学习“Java免费学习笔记(深入)”;
例如:
class FooWithField {
barField = "Hello World";
}初学者可能会误以为barField也会像barMethod一样被添加到FooWithField.prototype上。但实际情况并非如此:
const instance2 = new FooWithField(); console.log(instance2.barField); // 输出: Hello World console.log(FooWithField.prototype.barField); // 输出: undefined
从上述结果可以看出,barField并不存在于FooWithField.prototype上。那么,它究竟在哪里呢?
公共实例字段的声明,实际上是JavaScript引擎在实例化类时,将该字段直接添加到每个新创建的实例对象上。其内部机制等价于在类的constructor(构造函数)中,使用this关键字对属性进行赋值。
也就是说,以下两种写法在功能上是等价的:
使用公共实例字段:
class FooWithField {
barField = "Hello World";
}使用构造函数显式赋值:
class FooWithConstructor {
constructor() {
this.barField = "Hello World";
}
}无论哪种方式,barField都是实例自身的属性,而不是原型链上的属性。这意味着每个FooWithField或FooWithConstructor的实例都会拥有自己独立的barField副本。
const instA = new FooWithField(); const instB = new FooWithField(); console.log(instA.barField); // Hello World console.log(instB.barField); // Hello World instA.barField = "Modified A"; console.log(instA.barField); // Modified A console.log(instB.barField); // Hello World (instB的barField不受影响)
理解公共实例字段与原型方法的这种区别,对于编写高效且可维护的JavaScript类至关至要。它有助于避免对属性查找机制的误解,并能更准确地设计类的结构和行为。
以上就是深入理解JavaScript类中的公共实例字段与原型关联机制的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号