static members and instance members
The Difference Between Static Members and Instance Members
Static members belong to the class itself, while instance members belong to instances of the class. Static members are initialized when the class is loaded, whereas instance members are initialized when an object is created. Static members are accessed via the class name, and instance members are accessed through object instances.
class Car {
static wheels = 4; // Static property
brand: string; // Instance property
constructor(brand: string) {
this.brand = brand;
}
static getWheels() { // Static method
return Car.wheels;
}
getBrand() { // Instance method
return this.brand;
}
}
// Accessing static members
console.log(Car.wheels); // 4
console.log(Car.getWheels()); // 4
// Accessing instance members
const myCar = new Car('Toyota');
console.log(myCar.brand); // Toyota
console.log(myCar.getBrand()); // Toyota
Characteristics of Static Members
Static members are bound to the class, not to instances. All instances share the same static member, and modifying a static member affects all instances.
class Counter {
static count = 0;
constructor() {
Counter.count++;
}
static getCount() {
return Counter.count;
}
}
const c1 = new Counter();
const c2 = new Counter();
console.log(Counter.getCount()); // 2
Static methods cannot use the this
keyword to access instance members because static methods may be called before any instances are created.
Characteristics of Instance Members
Each instance has its own independent copy of instance members. Modifying an instance member of one object does not affect other instances.
class Person {
name: string;
constructor(name: string) {
this.name = name;
}
greet() {
console.log(`Hello, my name is ${this.name}`);
}
}
const p1 = new Person('Alice');
const p2 = new Person('Bob');
p1.greet(); // Hello, my name is Alice
p2.greet(); // Hello, my name is Bob
Instance methods can access other members of the current instance using the this
keyword.
Interaction Between Static and Instance Members
Static and instance members can interact with each other, but specific rules must be followed.
class Logger {
static logLevel = 'INFO';
static setLogLevel(level: string) {
Logger.logLevel = level;
}
log(message: string) {
console.log(`[${Logger.logLevel}] ${message}`);
}
}
const logger = new Logger();
logger.log('This is a test'); // [INFO] This is a test
Logger.setLogLevel('DEBUG');
logger.log('Debug message'); // [DEBUG] Debug message
Use Case Analysis
Static members are suitable for:
- Utility methods
- Constants or configurations
- Data shared among instances
class MathUtils {
static PI = 3.14159;
static circleArea(radius: number) {
return this.PI * radius * radius;
}
}
console.log(MathUtils.circleArea(5));
Instance members are suitable for:
- Object-specific properties
- Methods that depend on object state
- Scenarios requiring polymorphic behavior
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
makeSound() {
console.log('Some generic animal sound');
}
}
class Dog extends Animal {
makeSound() {
console.log('Woof! Woof!');
}
}
const myDog = new Dog('Buddy');
myDog.makeSound(); // Woof! Woof!
Special Considerations in TypeScript
TypeScript has some special handling for static members:
- Static members can be declared as
readonly
- Static members can have access modifiers
- Static members can implement interfaces
interface Loggable {
log(message: string): void;
}
class ConsoleLogger implements Loggable {
private static instance: ConsoleLogger;
private constructor() {}
static getInstance() {
if (!ConsoleLogger.instance) {
ConsoleLogger.instance = new ConsoleLogger();
}
return ConsoleLogger.instance;
}
log(message: string) {
console.log(message);
}
}
const logger = ConsoleLogger.getInstance();
logger.log('Singleton pattern with static member');
Static Members in Inheritance
Static members are also inherited. Subclasses can access static members of the parent class and can define their own static members.
class Parent {
static parentStatic = 'Parent static';
static parentStaticMethod() {
return 'Parent static method';
}
}
class Child extends Parent {
static childStatic = 'Child static';
static childStaticMethod() {
return `${this.parentStaticMethod()} + Child static method`;
}
}
console.log(Child.parentStatic); // Parent static
console.log(Child.childStaticMethod()); // Parent static method + Child static method
Application in Design Patterns
Static members are often used to implement design patterns, such as the Singleton pattern:
class Database {
private static instance: Database;
private constructor() {
// Initialization code
}
public static getInstance(): Database {
if (!Database.instance) {
Database.instance = new Database();
}
return Database.instance;
}
query(sql: string) {
// Execute query
}
}
const db1 = Database.getInstance();
const db2 = Database.getInstance();
console.log(db1 === db2); // true
Performance Considerations
Static members have only one copy in memory, saving memory space. Instance members have their own copy for each object, making them suitable for storing object-specific state.
class Particle {
static GRAVITY = 9.8;
x: number;
y: number;
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
update() {
this.y += Particle.GRAVITY;
}
}
// Create 1000 particles sharing the same GRAVITY value
const particles = Array(1000).fill(0).map((_, i) => new Particle(i, 0));
Common Mistakes and Pitfalls
- Incorrectly using
this
in static methods to access instance members - Confusing the access methods for static and instance members
- Overusing static members, making code difficult to test and maintain
class BadExample {
static sharedData = 'Shared';
instanceData: string;
constructor(data: string) {
this.instanceData = data;
}
static badMethod() {
// Error: Accessing instance members in a static method
// console.log(this.instanceData);
}
instanceMethod() {
// Correct: Accessing static members in an instance method
console.log(BadExample.sharedData);
}
}
Advanced Usage: Static Blocks
TypeScript 4.4+ supports static initialization blocks for complex static member initialization:
class Config {
static apiUrl: string;
static timeout: number;
static {
// Can execute complex initialization logic
this.apiUrl = process.env.API_URL || 'https://api.example.com';
this.timeout = parseInt(process.env.TIMEOUT || '5000');
}
}
console.log(Config.apiUrl);
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
上一篇:接口实现与类类型