Що означає, що Javascript є мовою на основі прототипу?


255

Однією з головних переваг Javascript, як кажуть, є те, що мова є прототипом.

Але що це означає, що Javascript заснований на прототипі, і чому це перевага?


3
Ця відповідь пояснює все , що вам потрібно знати про прототипну спадкуванні: stackoverflow.com/a/16872315/783743
Aadit M Shah

Відповіді:


291

Прототипне успадкування - це форма використання об'єктно-орієнтованого коду . Javascript - одна з єдиних [основних] об'єктно-орієнтованих мов, що використовують успадкування прототипів. Майже всі інші об'єктно-орієнтовані мови є класичними.

У класичному успадкуванні програміст пише клас, який визначає об’єкт. Кілька об'єктів можна інстанціювати з одного класу, тому у вас є код в одному місці, який описує кілька об’єктів у вашій програмі. Потім класи можуть бути організовані в ієрархію, що сприятиме подальшому використанню коду. Більш загальний код зберігається у класі вищого рівня, від якого успадковують класи нижчого рівня. Це означає, що об’єкт ділиться кодом з іншими об'єктами того ж класу, а також з його батьківськими класами.

У прототипічній формі успадкування об’єкти успадковують безпосередньо від інших об'єктів. Вся справа про заняття минає. Якщо ви хочете об'єкт, ви просто записуєте об'єкт. Але повторне використання коду все ще є цінною річчю, тому об’єкти дозволяється з'єднувати разом в ієрархії. У javascript кожен об'єкт має таємне посилання на об'єкт, який його створив, утворюючи ланцюжок. Коли об’єкт запитує властивість, якої у нього немає, його батьківський об’єкт буде запитувати ... постійно в ланцюзі, поки не буде знайдено властивість або до досягнення кореневого об'єкта.

Кожна функція JavaScript (яка є самими об'єктами) насправді має член, який називається "прототип", який відповідає за надання значень, коли об'єкт запитується на них. Наявність цього члена дозволяє механізму конструктора (за допомогою якого об'єкти будуються з функцій) працювати. Додавання властивості до прототипу функціонального об'єкта зробить його доступним для побудованого об'єкта, а також для всіх об'єктів, які успадковуються від нього.

Переваги

Можливо, не існує жорсткого і швидкого правила щодо того, чому успадкування прототипів є вигідною формою повторного використання коду. Саме повторне використання коду є вигідним, а успадкування прототипів - це розумний спосіб зробити це. Ви можете стверджувати, що успадкування прототипів є досить простою моделлю повторного використання коду, і що код може бути сильно використаний прямим способом . Але класичні мови, безумовно, здатні досягти і цього.

Sidenote: @Andrew Hedges вказує на те, що насправді існує багато мов прототипів. Варто зазначити, що ці інші існують, але також варто зазначити, що жоден з них не є близьким до мейнстріму. Начебто NewtonScript на деякий час мав деяку тягу, але загинув з його платформи. Можливо також розширити деякі сучасні мови способами, що додають прототипних можливостей.


9
Гей Келлі. Хоча JavaScript є безумовно найпопулярнішим прототіпічного мовою, є багато інших: en.wikipedia.org/wiki/Prototype-based_programming#Languages
Andrew Hedges

2
Гей Ендрю. Гарна думка. Я повинен був бути більш чітким. Я заноту про це.
кепаро

3
Прочитайте також це developer.mozilla.org/uk/JavaScript/Guide/…
pramodc84

1
+1 за чудову відповідь. Один незначний коментар: Мені класичне успадкування здається більш "прямим", ніж прототипним. Насправді я дійсно бачу об’єкт-прототип як просту зв'язок (з іншими об'єктами), тоді як у складеному OOP я вважаю базовий клас "безпосередньо успадкованим". Як такі, прототипні об'єкти пов'язані ланцюжком, а не успадковуються (успадкування дещо підроблене). Будь-які думки?
В'язень ЗЕРО

3
@PrisonerZERO: Я б стверджував, що успадкування прототипів є більш прямим, ніж класичне. Замість об'єкта B вказує на клас, який успадковує клас, на який вказує об'єкт A, він вказує безпосередньо на об'єкт A і каже "я такий самий, як об'єкт, за винятком ...". Найважливіше значення щодо успадкування прототипів, і те, що більшості людей здається найскладнішим для інтерналізації, - це те, що воно не відрізняє випадки від типів. Кожен об’єкт є і типом, і екземпляром. Відмінність між цими двома є штучними та навмисними, і, як правило, є симптомом застрягання у класно-орієнтованому мислення.
cHao

54

Мова, заснована на прототипі, не робить різниці між класами та об'єктами: у неї просто є об'єкти. Мова, заснована на прототипі, має поняття прототипного об'єкта, об'єкта, який використовується як шаблон, з якого можна отримати початкові властивості нового об’єкта. Будь-який об'єкт може вказати свої власні властивості, коли ви створюєте його, так і під час виконання. Крім того, будь-який об’єкт може бути асоційований як прототип для іншого об'єкта , дозволяючи другому об'єкту ділитися властивостями першого об'єкта.


6
Дуже хороше пояснення, але трохи оману з коментарем про "шаблон початкових властивостей". Якщо ви зміните прототип ПІСЛЯ інстанціювання об'єкта, цей об'єкт все одно отримує ці функції.
nickf

32

Прототипове програмування - це стиль об'єктно-орієнтованого програмування, де класів немає, а повторне використання (або успадкування мов на основі класів) здійснюється шляхом клонування існуючих об'єктів, які служать прототипами.


Ви все ще відчуваєте себе таким чином? Бо якщо так, то це перше пояснення, яке коли-небудь дійсно просто «клацнуло» зі мною.
Chazt3n

11

Перевага / недолік полягає в тому, що ми можемо створювати нові види об'єктів під час виконання без необхідності визначення класів (статичний код). Як і більшість функцій, розробник повинен перетворити це на перевагу / недолік.

Вище можливо, тому що об’єкти по суті є функціями в сценарії Java (також закриття).


Динамічні об'єкти є перевагою javascript, але вони насправді не пов'язані з тим, що javascript є прототиповою або функціональною мовою. У багатьох класичних мовах ви можете створювати динамічні об'єкти під час виконання. Закриття дещо не пов'язані також.
кепаро

2
Класи не обов'язково є статичним кодом - погляньте на Python, в якому класи - це самі об'єкти, і вони побудовані з метакласів, які також є об'єктами.
Томаш Зелінський

6

Замість того, щоб оголосити структуру класу, ви можете створювати об'єкти одного типу та додавати до їх визначення будь-який час, коли вам подобається, використовуючи прототип об’єкта. Це більш гнучко, ніж звичайний спосіб робити речі.


6

Якщо ви просто використовуєте об'єкти під час виконання замість класу при компіляції для створення нових об'єктів, це відкриває можливість розширення об'єкта, не знаючи про нього деталей. Звичайно, це може стати недоліком досить швидко залежно від використання. Я не припускаю, що мова йде тут, тому вона застосовна для інших мов, крім javascript, які не такі динамічні.

myobject.prototype=unkownobject;
myobject.newproperty=1;

Ви можете отримати об’єкт практично з будь-якого місця; власний код, з мережі, з бази даних, із зовнішніх зв'язків тощо.

Зауважте, що мова не повинна реалізовувати успадкування прототипу, як JavaScript. У javascript об’єкт-прототип просто поділяється, як і його властивості, серед спадкоємців. Альтернативою є копіювання всіх властивостей прототипу на новий об’єкт. Кожен підхід має свої сильні сторони в різних ситуаціях. Мені більше подобається друге, але це не те, що робить JavaScript.


6

Прочитавши всі відповіді, це висновок

1) Спадкування, при якому об'єкти успадковуються безпосередньо від інших об'єктів

2) Це не використовує класи

3) Також називається програмування, засноване на екземплярі, або безкласне програмування, орієнтоване на прототип

4) Повторне використання поведінки здійснюється шляхом клонування існуючих об'єктів, які служать прототипами

5) Об'єкт, використаний як шаблон нового об'єкта, отримує початкові властивості

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.