Loading...

Статикалык касиеттер жана методдор

Статикалык касиеттер жана методдор

 

Биз класстын өзүнө да методду дайындай алабыз. Мындай ыкмалар статикалык деп аталат .

Алар класс декларациясына ачкыч сөз менен кошулат 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аларды салыштыруунун каражаты катары макалалардын "үстүндө" турат. Бул бир макаланын ыкмасы эмес, бүткүл класстын ыкмасы.

Дагы бир мисал, «заводдук» деп аталган ыкманы алсак болот.

Биз макаланы түзүү үчүн бир нече жолдору керек дейли:

  1. Белгиленген параметрлер аркылуу түзүү ( titledateж.б.).
  2. Бүгүнкү күн менен бош макала түзүңүз.
  3. …же башка бир нерсе.

Биринчи жолду конструктор аркылуу ишке ашырууга болот. Ал эми экинчиси үчүн, сиз статикалык класс ыкмасын колдоно аласыз.

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

Жаңы мүмкүнчүлүк
Бул өзгөчөлүк тилге жакында кошулган. Мисалдар акыркы Chrome'до иштейт.

Статикалык касиеттер да болушу мүмкүн, алар класстык касиеттерге окшош, бирок 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ал прототипке эки шилтеме жаратат:

  1. Функция Rabbitпрототиптик түрдө функциядан мураска алат Animal.
  2. 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прототиби үчүн AB.[[Prototype]] = A. Ошентип, талаа табылбаса B, издөө уланат A.

Tasks

маанилүүлүгү: 3

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@