Галоўная > Разбор пытанняў з рэальных сумоўяў JS. - Што можна зрабіць з class у JS і нельга зрабіць з constructor function

Разбор пытанняў з рэальных сумоўяў JS. - Што можна зрабіць з class у JS і нельга зрабіць з constructor function

сумоўе
js

tech_interview

Пытанне

Што можна зрабіць з класамі у JS і нельга зрабіць з функцыямі-канструктарамі

Кароткі адказ

  • Успадкоўванне (inheritance) ад ўбудаваных тыпаў, такіх як Array ці Error складанае ці немагчымае.

Падрабязны адказ

Давайце разгледзім адрозненні класаў і функцый-канструктараў:

1) Розны сінтаксіс і пазначэнне наследвання:

Для класаў:

class Child extends Parent { ... }

Для функцый-канструктараў:

function Child() {
  Parent.call(this);
}

2) Стварэнне экзэмпляра раней аб'явы канструктара:

Функцыю-канструктар можна выкарыстаць, а потым аб'явіць (function declaration).

Класы немагчыма выкарыстаць да іх аб'явы.

3) Стварэнне экзэмпляра

Клас нельга выклікаць без new, функцыю-канструктар - можна

4) Метады класа вызначаюцца ў прататыпе

Метады, вызначаныя ў блоку класа, аўтаматычна становяцца часткай прататыпа аб'екта, у адрозненне ад функцый-канструктараў, дзе метады трэба відавочна дадаваць да прататыпа.

class MyClass {
  myMethod() { ... }
}

5) Метады экзэмпляра класа і функцыі-канструктара

Метады экзэмпляра класа з'яўляюцца непералічальнымі. Вызначэнне класа усталёўвае сцяг enumerable у false для ўсіх метадаў у prototype. І гэта добра, бо калі мы праходзімся цыклам for..in па аб'екце, то звычайна мы не жадаем пры гэтым атрымліваць метады класа.

Метады экзэмпляра ад функцыі-канструктара трапяць у пералік цыкла for...in у абодвух выпадках - калі яны запісаныя ў prototype ці калі яны запісаныя ў самой функцыі-канструктары).

6) strict mode

Класы заўжды выкарыстоўваюць use strict. Увесь код аўтаматычна знаходзіцца ў строгім рэжыме.

7) Статычныя метады і ўласцівасці

Класы дазваляюць вызначаць статычныя метады і ўласцівасці з дапамогай ключавога слова static. Гэтыя метады і ўласцівасці належаць самому класу, а не яго экзэмплярам.

class MyClass {
  static staticMethod() { ... }
}

Для функцый-канструктараў магчыма дадаць статычныя метады з дапамогай выкарыстання функцыі як аб'екта:

function F() {}

F.staticMethod = function() {}

8) Гетэры і сетэры

У класах можна выкарыстоўваць гетары і сетэры для стварэння вылічаных уласцівасцяў.

class MyClass {
  get computedProp() { ... }
  set computedProp(value) { ... }
}

У функцыях-канструктарах у JavaScript гетэры і сетэры можна рэалізаваць у самим канструктары, выкарыстаючы Object.defineProperty(), або непасрэдна ў прататыпе канструктара.

Вось першы варыянт:

function MyFunc() {
    let private = 'secret';

    Object.defineProperty(this, 'myProp', {
        get: function() {
            return private;
        },
        set: function(value) {
            private = value;
        },
        enumerable: true,
        configurable: true
    });
}

const myInstance = new MyFunc();
console.log(myInstance.myProp);  // Атрымаць значэнне
myInstance.myProp = 'new value'; // Усталяваць новае значэнне
console.log(myInstance.myProp);  // 'new value'

9) Прыватныя палі і метады

З класамі можна выкарыстоўваць прыватныя палі і метады, што немагчыма зрабіць з функцыямі-канструктарамі без замыканняў. Але нават з замыканнямі рэалізацыя будзе крыху адрознівацца па сінтаксісе і паводзінах:

  • прыватныя пераменныя не звязаныя напрамую з экзэмплярамі аб'екта.
  • У класах кожны экзэмпляр мае сваю копію прыватных палёў. У функцыях-канструктарах з замыканнямі, прыватныя пераменныя існуюць у адзіным экзэмпляры ў рамках замыкання, і не дублююцца для кожнага экзэмпляра аб'екта.
class MyClass {
  #privateField;
  #privateMethod() { ... }
}

10) Успадкоўванне (inheritance) ад ўбудаваных тыпаў

Класы дазваляюць успадкаваць ад ўбудаваных тыпаў, такіх як Array або Error, што складана ці немагчыма зрабіць з функцыямі-канструктарамі:

  • Некаторыя унутраныя уласцівасци убудаваных класаў, такіх як даўжыня масіва (length у Array) або стэк выклікаў (stack у Error) маюць асаблівую рэалізацыю і не будуць працаваць карэктна.
  • Пры выкарыстанні функцый-канструктараў для ўспадкоўвання ад убудаваных тыпаў могуць ўзнікнуць праблемы з правільнай усталёўкай ланцужкоў прататыпаў.
  • Некаторыя JavaScript-рухавікі могуць мець абмежаванні або спецыфічную рэалізацыю, якая ускладняе або робіць немагчымым ўспадкоўванне ад убудаваных тыпаў.
  • Некаторыя ўбудаваныя тыпы могуць быць рэалізаваны такім чынам, што яны не маюць на ўвазе магчымасці атрымання ў спадчыну або маюць абмежаванні на гэты працэс.

То бок, мы атрымліваем розніцу ў паводзінах прыватных палей і метадаў і маем абмежаванні ў выкарыстоўванні ўспадкоўвання ад убудаваных тыпаў.

P.S.: калі вы маеце якія іншыя меркаванні, дадайце, калі ласка, іх у каментарах.

loveJS, 2023-12-17
Каментары

    (Каб даслаць каментар залагуйцеся ў свой уліковы запіс)

    ;