Биз класстын өзүнө да методду дайындай алабыз. Мындай ыкмалар статикалык деп аталат .
Алар класс декларациясына ачкыч сөз менен кошулат static
, мисалы:
@A@class User {
static staticMethod() {
alert(this === User);
}
}
User.staticMethod(); // true
Бул ыкманы түздөн-түз функция касиети катары дайындоо менен бирдей:
class User { }
User.staticMethod = function() {
alert(this === User);
};
this
Чакыруунун мааниси User.staticMethod()
класстын конструкторунун өзү User
("объект чекит" эрежеси).
Эреже катары, статикалык методдор класска бүтүндөй, жалпысынан таандык болгон жана ошол эле учурда кандайдыр бир жеке объектилерге тиешеси жок функцияларды ишке ашыруу үчүн колдонулат.
Абдан ачык угулат эмеспи? Эми баары өз ордуна келет.
Мисалы, макала объекттери бар Article
жана аларды салыштыруу үчүн сизге функция керек.
Табигый чечим бул үчүн статикалык ыкманы жасоо болуп саналат Article.compare
:
@A@class Article {
constructor(title, date) {
this.title = title;
this.date = date;
}
static compare(articleA, articleB) {
return articleA.date - articleB.date;
}
}
// использование
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
аларды салыштыруунун каражаты катары макалалардын "үстүндө" турат. Бул бир макаланын ыкмасы эмес, бүткүл класстын ыкмасы.
Дагы бир мисал, «заводдук» деп аталган ыкманы алсак болот.
Биз макаланы түзүү үчүн бир нече жолдору керек дейли:
- Белгиленген параметрлер аркылуу түзүү (
title
,date
ж.б.). - Бүгүнкү күн менен бош макала түзүңүз.
- …же башка бир нерсе.
Биринчи жолду конструктор аркылуу ишке ашырууга болот. Ал эми экинчиси үчүн, сиз статикалык класс ыкмасын колдоно аласыз.
Article.createTodays()
Төмөнкү мисалдагыдай :
class Article {
constructor(title, date) {
this.title = title;
this.date = date;
}
static createTodays() {
// помним, что this = Article
return new this("Сегодняшний дайджест", new Date());
}
}
let article = Article.createTodays();
alert( article.title ); // Сегодняшний дайджест@A@
Эми, биз бүгүнкү дайджестти түзүшүбүз керек болгон сайын, чалышыбыз керек Article.createTodays()
. Дагы бир жолу айта кетейин, бул бир макаланын ыкмасы эмес, бүткүл класстын ыкмасы.
Статикалык методдор маалыматтар базасынын жазууларын табуу/сактоо/жок кылуу үчүн маалымат базасынын класстарында да колдонулат, мисалы:
// предположим, что Article - это специальный класс для управления статьями
// статический метод для удаления статьи по id:
Article.remove({id: 12345});
Статикалык методдорду класстарда чакырса болот, бирок айрым объекттерде эмес.
Мисалы. мындай код иштебейт:
@A@// ...
article.createTodays(); /// Error: article.createTodays is not a function@A@
Static Properties
Статикалык касиеттер да болушу мүмкүн, алар класстык касиеттерге окшош, бирок static
:
@A@class Article {
static publisher = "Илья Кантор";
}
alert( Article.publisher ); // Илья Кантор
Бул түздөн-түз дайындоо менен бирдей Article
:
Article.publisher = "Илья Кантор";@A@
Статикалык касиеттерди жана методдорду мурастоо
Статикалык касиеттери жана ыкмалары тукум кууган.
Мисалы, Animal.compare
төмөндөгү коддогу ыкма мураска алынган жана төмөнкүдөй жеткиликтүү Rabbit.compare
@A@class Animal {
constructor(name, speed) {
this.speed = speed;
this.name = name;
}
run(speed = 0) {
this.speed += speed;
alert(`${this.name} бежит со скоростью ${this.speed}.`);
}
static compare(animalA, animalB) {
return animalA.speed - animalB.speed;
}
}
// Наследует от Animal
class Rabbit extends Animal {
hide() {
alert(`${this.name} прячется!`);
}
}
let rabbits = [
new Rabbit("Белый кролик", 10),
new Rabbit("Чёрный кролик", 5)
];
rabbits.sort(Rabbit.compare);
rabbits[0].run(); // Чёрный кролик бежит со скоростью 5.@A@
Биз чалсак болот Rabbit.compare
, ал мураска калгандарды чакырат Animal.compare
.
Бул кандай иштейт? Кайрадан прототиптерди колдонуу. Сиз ойлогондой, extends
ал Rabbit
шилтемени [[Prototype]]
берет Animal
.
Ошентип, Rabbit extends Animal
ал прототипке эки шилтеме жаратат:
- Функция
Rabbit
прототиптик түрдө функциядан мураска алатAnimal
. Rabbit.prototype
прототиптик жактан мураска алатAnimal.prototype
.
Натыйжада, мурас регулярдуу жана статикалык ыкмалар үчүн иштейт.
Келгиле, аны код менен текшерип көрөлү:
@A@class Animal {}
class Rabbit extends Animal {}
// для статики
alert(Rabbit.__proto__ === Animal); // true
// для обычных методов
alert(Rabbit.prototype.__proto__ === Animal.prototype); // true@A@
Бардыгы
Статикалык методдор функционалдуулук үчүн колдонулат, "жалпысынан" классына кирет жана белгилүү бир класс объектисине кирбейт.
Мисалы, эки макаланы салыштыруу ыкмасы Article.compare(article1, article2)
же заводдук ыкма Article.createTodays()
.
Класс декларациясында алар ачкыч сөз менен белгиленет static
.
Статикалык касиеттер биз маалыматтарды бир эле объект эмес, класс деңгээлинде сактагыбыз келген учурларда колдонулат.
Синтаксис:
@A@class MyClass {
static property = ...;
static method() {
...
}
}@A@
Техникалык жактан алганда, статикалык декларация класска тапшырма менен бирдей:
@A@MyClass.property = ...
MyClass.method = ...@A@
Статикалык касиеттери жана ыкмалары тукум кууган.
class B extends A
Класстын B
прототиби үчүн A
: B.[[Prototype]] = A
. Ошентип, талаа табылбаса B
, издөө уланат A
.
Tasks
Object.prototype
Бизге белгилүү болгондой, бардык объекттер объекттин "жалпы" ыкмаларынан мураска алышат жана аларга кирүү мүмкүнчүлүгү бар, мисалы hasOwnProperty
.
Мисал:
@A@class Rabbit {
constructor(name) {
this.name = name;
}
}
let rabbit = new Rabbit("Rab");
// метод hasOwnProperty от Object.prototype
alert( rabbit.hasOwnProperty('name') ); // true@A@
Бирок биз ачык жазсакчы "class Rabbit extends Object"
- анда натыйжа кадимкиден башкача болот "class Rabbit"
?
Айырмасы эмнеде?
Төмөндө мындай мураска ээ коддун мисалы келтирилген (эмне үчүн ал иштебейт? Аны оңдоо):
@A@class Rabbit extends Object {
constructor(name) {
this.name = name;
}
}
let rabbit = new Rabbit("Кроль");
alert( rabbit.hasOwnProperty('name') ); // Ошибка@A@