实例成员&静态成员

发布于 2025-02-05  626 次阅读


在JavaScript中,特别是在使用类或构造函数创建对象时,我们经常会遇到“实例成员”和“静态成员”这两个概念。

实例成员(Instance Members)

实例成员是属于类(或构造函数创建的)的实例(对象)的属性或方法。每个通过new关键字创建的实例都会有自己的一份实例成员副本(除非该成员是引用类型并且被共享)。实例成员是通过在类定义中的constructor方法内部定义,或者在类体内部但不在任何方法内部直接定义(这样它们会成为实例的属性)来创建的。

示例

class MyClass {
  constructor(value) {
    this.instanceProperty = value; // 实例属性
  }

  instanceMethod() {
    console.log('This is an instance method.'); // 实例方法
  }
}

const instance1 = new MyClass('Value 1');
const instance2 = new MyClass('Value 2');

console.log(instance1.instanceProperty); // 输出: Value 1
console.log(instance2.instanceProperty); // 输出: Value 2

instance1.instanceMethod(); // 调用实例方法

静态成员(Static Members)

静态成员是属于类本身而不是其任何实例的属性或方法。静态成员不会在每个实例上创建副本,而是作为类的一部分共享。它们通常用于为类提供工具函数或常量,这些函数或常量与类的任何特定实例无关。静态成员使用static关键字在类定义中声明。

示例

class MyClass {
  static staticProperty = 'This is a static property.'; // 静态属性

  static staticMethod() {
    console.log('This is a static method.'); // 静态方法
  }
}

console.log(MyClass.staticProperty); // 输出: This is a static property.
MyClass.staticMethod(); // 调用静态方法

// 注意:不能通过实例访问静态成员
// console.log(instance1.staticProperty); // 会抛出错误
// instance1.staticMethod(); // 会抛出错误

以下是通过构造函数形式展示实例成员和静态成员的示例

构造函数形式的实例成员和静态成员

在JavaScript中,构造函数用于创建对象,并且可以在这些对象上定义实例成员。同时,构造函数本身也可以有静态成员,这些成员不属于任何实例,而是属于构造函数本身。

实例成员

实例成员是定义在构造函数prototype上的属性或方法,或者是在构造函数内部使用this关键字定义的属性。每个通过new关键字创建的实例都会继承构造函数prototype上的属性和方法,并且可以有自己的实例属性副本。

静态成员

静态成员是定义在构造函数本身上的属性或方法,它们使用构造函数名.属性名构造函数名.方法名的形式来访问,而不是通过实例来访问。

示例代码

// 定义一个构造函数
function MyConstructor(value) {
  // 实例属性
  this.instanceProperty = value;

  // 实例方法
  this.instanceMethod = function() {
    console.log('This is an instance method. Instance property value:', this.instanceProperty);
  };
}

// 给构造函数的prototype添加实例方法(这也是一种常见做法)
MyConstructor.prototype.anotherInstanceMethod = function() {
  console.log('This is another instance method.');
};

// 静态属性
MyConstructor.staticProperty = 'This is a static property.';

// 静态方法
MyConstructor.staticMethod = function() {
  console.log('This is a static method.');
};

// 创建实例
const instance1 = new MyConstructor('Value 1');
const instance2 = new MyConstructor('Value 2');

// 访问实例成员
console.log(instance1.instanceProperty); // 输出: Value 1
instance1.instanceMethod(); // 调用实例方法
instance1.anotherInstanceMethod(); // 调用通过prototype添加的实例方法

// 访问静态成员(注意:不能通过实例访问静态成员)
console.log(MyConstructor.staticProperty); // 输出: This is a static property.
MyConstructor.staticMethod(); // 调用静态方法

// 尝试通过实例访问静态成员会失败(会返回undefined或抛出错误,取决于具体实现)
// console.log(instance1.staticProperty); // undefined
// instance1.staticMethod(); // TypeError: instance1.staticMethod is not a function

在这个例子中,MyConstructor是一个构造函数,它有两个实例属性(instanceProperty是通过构造函数内部定义的,而另一个实例方法是通过prototype添加的),以及两个静态成员(staticPropertystaticMethod)。我们创建了两个实例instance1instance2,并展示了如何访问它们的实例成员以及构造函数的静态成员。

请注意,虽然在这个例子中我们直接在构造函数内部定义了instanceMethod,但在实际应用中,通常更推荐在prototype上定义方法,因为这样可以避免在每个实例上都创建方法的新副本,从而提高内存效率。上面的代码中已经展示了如何通过prototype添加实例方法(anotherInstanceMethod)。

总结

  • 实例成员:属于类的实例(对象),每个实例都有自己的一份副本。可以通过挂载prototype让每一个实例都共享该方法
  • 静态成员:属于类本身,与任何实例无关,由类共享。
下次见面会是什么时候呢?
最后更新于 2025-02-05