كما يمكننا تعيين خاصية لدالة الclass ذاتها, وليس لـ "prototype"
الخاص بها. مثل هذه الدوال تسمى بـstatic.
في الـ class, يتم إلحاقهم بكلمة رئيسية static
’’ ، مثل هذا:
class User {
static staticMethod() {
alert(this === User);
}
}
User.staticMethod(); // true
هذا في الواقع يفعل نفس الشيء عند تعيينه كخاصية مباشرة:
class User {}
User.staticMethod = function () {
alert(this === User);
};
User.staticMethod(); // true
قيمة this
فيUser.staticMethod ()
هي مُنشئ الفئةالمستخدم
نفسه (قاعدة “object قبل النقطة”).
عادة ، يتم استخدام الأساليب الثابتة لتنفيذ الوظائف التي تنتمي إلى الفئة ، ولكن ليس لأي object معين منها.
على سبيل المثال ، لدينا objects Article
ونحتاج إلى وظيفة لمقارنتها. الحل الطبيعي هو إضافة طريقة Article.compare
، على النحو التالي:
class Article {
constructor(title, date) {
this.title = title;
this.date = date;
}
static compare(articleA, articleB) {
return articleA.date - articleB.date;
}
}
// usage
let articles = [
new Article("HTML", new Date(2019, 1, 1)),
new Article("CSS", new Date(2019, 0, 1)),
new Article("JavaScript", new Date(2019, 11, 1))
];
articles.sort(Article.compare);
alert( articles[0].title ); // CSS
هنا “Article.compare” تقف المقالات “أعلاه” ، كوسيلة لمقارنتها. إنها ليست دالة لـ article
، ولكن بدلاً من الـ class
بأكمله.
مثال آخر هو ما يسمى طريقة “المصنع”. تخيل ، نحن بحاجة إلى طرق قليلة لإنشاء مقال:
- إنشاء بواسطة معلمات معينة (
العنوان
،التاريخ
وما إلى ذلك). - إنشاء مقال فارغ بتاريخ اليوم.
- … أو بطريقة أخرى.
يمكن تنفيذ الطريقة الأولى من قبل المنشئ. وللثاني يمكننا عمل طريقة ثابتة للفئة.
مثل Article.createTodays()
هنا:
class Article {
constructor(title, date) {
this.title = title;
this.date = date;
}
static createTodays() {
// remember, this = Article
return new this("Today's digest", new Date());
}
}
let article = Article.createTodays();
alert( article.title ); // Today's digest
الآن في كل مرة نحتاج فيها إلى إنشاء ملخص اليوم ، يمكننا استدعاء ``Article.createTodays ()`. مرة أخرى ، هذه ليست طريقة لمقالة ، ولكنها طريقة للفصل بأكمله.
يتم استخدام الأساليب الثابتة أيضًا في الفئات المتعلقة بقاعدة البيانات للبحث / حفظ / إزالة الإدخالات من قاعدة البيانات ، مثل هذا:
// assuming Article is a special class for managing articles
// static method to remove the article:
Article.remove({ id: 12345 });
Static properties
الخصائص الثابتة ممكنة أيضًا ، فهي تبدو مثل خصائص الفئة العادية ، ولكن يتم إلحاقها بـ static
:
class Article {
static publisher = 'Ilya Kantor';
}
alert(Article.publisher); // Ilya Kantor
That is the same as a direct assignment to Article
:
Article.publisher = 'Ilya Kantor';
Inheritance of static properties and methods
الخصائص والأساليب الثابتة موروثة.
على سبيل المثال ، Animal.compare
وAnimal.planet
في الشفرة أدناه موروثة ويمكن الوصول إليها باسم Rabbit.compare
وRabbit.planet
:
class Animal {
static planet = "Earth";
constructor(name, speed) {
this.speed = speed;
this.name = name;
}
run(speed = 0) {
this.speed += speed;
alert(`${this.name} runs with speed ${this.speed}.`);
}
static compare(animalA, animalB) {
return animalA.speed - animalB.speed;
}
}
// Inherit from Animal
class Rabbit extends Animal {
hide() {
alert(`${this.name} hides!`);
}
}
let rabbits = [
new Rabbit("White Rabbit", 10),
new Rabbit("Black Rabbit", 5)
];
rabbits.sort(Rabbit.compare);
rabbits[0].run(); // Black Rabbit runs with speed 5.
alert(Rabbit.planet); // Earth
الآن عندما نسمي “Rabbit.compare” ، سيتم استدعاء “Animal.compare” الموروث.
كيف يعمل؟ مرة أخرى ، باستخدام النماذج الأولية. كما كنت قد خمنت بالفعل ، فإن كلمة “يمتد” تعطي كلمة “أرنب” يشير "[[نموذج أولي]]` إلى “حيوان”.
So, Rabbit extends Animal
creates two [[Prototype]]
references:
Rabbit
function prototypally inherits fromAnimal
function.Rabbit.prototype
prototypally inherits fromAnimal.prototype
.
As a result, inheritance works both for regular and static methods.
Here, let’s check that by code:
class Animal {}
class Rabbit extends Animal {}
// for statics
alert(Rabbit.__proto__ === Animal); // true
// for regular methods
alert(Rabbit.prototype.__proto__ === Animal.prototype); // true
ملخص
يتم استخدام الأساليب الثابتة للوظيفة التي تنتمي إلى الفئة “ككل”. لا يتعلق الأمر بمثيل فئة ملموسة.
على سبيل المثال ، طريقة للمقارنة Article.compare (article1 ، article2)
أو طريقة مصنع Article.createTodays ()
.
يتم تسميتها بكلمة “ثابت” في إعلان الفئة.
يتم استخدام الخصائص الثابتة عندما نرغب في تخزين البيانات على مستوى الفصل الدراسي ، والتي لا ترتبط أيضًا بمثيل.
الصيغة هي:
class MyClass {
static property = ...;
static method() {
...
}
}
من الناحية الفنية ، فإن الإعلان الثابت هو نفسه التخصيص للـ class
نفسها:
MyClass.property = ...
MyClass.method = ...
الخصائص والأساليب الثابتة موروثة.
بالنسبة إلى “الفئة B التي تمد A” ، يشير النموذج الأولي للفئة B
نفسها إلىA
: B. [[Prototype]] = A
. لذا ، إذا لم يتم العثور على حقل في B
، فسيستمر البحث فيA
.