مقدمه

متدها و پراپرتی‌های استاتیک (static) در کلاس‌ها برای تعریف رفتار یا داده‌هایی به کار می‌روند که وابسته به نمونه (instance) نیستند، بلکه به خود کلاس مرتبط‌اند. این امکان برای ابزارهای کمکی، شمارنده‌ها یا متدهایی که نیازی به داده‌های هر نمونه ندارند، ایده‌آل است. با کلمه کلیدی static می‌توانید متد یا پراپرتی را مستقیماً به کلاس متصل کنید، نه به نمونه‌ها. این متدها و ویژگی‌ها فقط از طریق خود کلاس قابل دسترسی‌اند و نمونه‌ها آن‌ها را به ارث نمی‌برند.

سینتکس و کاربرد اعضای استاتیک

متد یا پراپرتی استاتیک درون تعریف کلاس، با پیشوند static مشخص می‌شود. برای استفاده از آن‌ها باید از نام کلاس و نه نمونه استفاده کنید.

در مثال زیر متد استاتیک info و پراپرتی استاتیک count تعریف شده است. با ساخت هر نمونه، مقدار count افزایش می‌یابد.

Copy Icon JAVASCRIPT
class User {
  static count = 0;
  constructor(name) {
    this.name = name;
    User.count++;
  }
  static info() {
    console.log("Count:", User.count);
  }
}

let u1 = new User("ali");
let u2 = new User("sara");
User.info(); // Count: 2
console.log(u1.info()); // undefined

همانطور که می‌بینید، متد و پراپرتی استاتیک فقط از طریق خود کلاس User قابل دسترسی هستند و نمونه‌های ساخته‌شده (مثل u1 و u2) به آن‌ها دسترسی ندارند. اگر تلاش کنید متد استاتیک را روی نمونه صدا بزنید، نتیجه undefined خواهد بود.

ابزارهای کمکی (Utility) با static

امکان تعریف اعضای استاتیک برای متدهای کمکی مثل تبدیل واحد، اعتبارسنجی داده یا تولید مقادیر تصادفی بدون نیاز به نمونه کلاس، بسیار مناسب است. برای مثال در کد زیر یک کلاس با نام MathHelper تعریف شده که دو متد استاتیک دارد: یکی برای تبدیل درجه به رادیان و دیگری برای تولید یک عدد صحیح تصادفی از یک بازه‌ی دلخواه.

Copy Icon JAVASCRIPT
class MathHelper {
    static toRadian(degree) {
        return degree * Math.PI / 180;
    }
    static randomInt(min, max) {
        return Math.floor(Math.random() * (max - min + 1)) + min;
    }
}

console.log(MathHelper.toRadian(90)); // 1.5707963267948966
console.log(MathHelper.randomInt(1, 10)); // عددی بین 1 تا 10
                    

همانطور که می‌بینید، بدون نیاز به ساخت نمونه از MathHelper می‌توانیم متدهای کمکی را مستقیماً از طریق کلاس صدا بزنیم.

ارث‌بری متدهای استاتیک

کلاس‌های فرزند هم متدها و پراپرتی‌های استاتیک والد را به ارث می‌برند و می‌توانند آن‌ها را بازنویسی (override) کنند. این متدها با استفاده از نام کلاس فرزند صدا زده می‌شوند. مثال زیر را ببینید.

Copy Icon JAVASCRIPT
class Animal {
  static type() {
    return "animal";
  }
}

class Dog extends Animal {}

console.log(Dog.type()); // animal

اما همانطور گه گفته شد، کلاس فرزند می‌تواند متد استاتیک کلاس والد را بازنویسی هم بکند؛ کاری که در مثال زیر انجام شده است.

Copy Icon JAVASCRIPT
class Vehicle {
    static category() {
        return "transport";
    }
}

class Car extends Vehicle {
    static category() {
        return "car";
    }
}

console.log(Vehicle.category()); // transport
console.log(Car.category()); // car
                    

در این مثال، کلاس Car متد استاتیک category را بازنویسی کرده است و خروجی آن با کلاس والد متفاوت است.

برای رفتارهایی که همه نمونه‌ها باید به صورت مشترک استفاده کنند (مثل شمارنده کل یا متدهای utility)، متد یا پراپرتی را استاتیک تعریف کنید تا کد تمیز و قابل نگهداری داشته باشید. در واقع، بر خلاف متدها و پراپرتی‌های غیر استاتیک که در سطح نمونه (instance-level) هستند و از نمونه‌ای به نمونه‌ی دیگر متفاوت هستند، متدها و پراپرتی‌های استاتیک در سطح کلاس (class-level) هستند و بین همه‌ی نمونه‌ها مشترک هستند.