Разбор пытанняў з рэальных сумоўяў JS. - Што можна зрабіць з class у JS і нельга зрабіць з constructor function
Пытанне
Што можна зрабіць з класамі у 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.: калі вы маеце якія іншыя меркаванні, дадайце, калі ласка, іх у каментарах.
Каментары
(Каб даслаць каментар залагуйцеся ў свой уліковы запіс)