Прототип JavaScript, пояснений на прикладах

Прототипи

JavaScript - це мова, заснована на прототипі, тому розуміння об’єкта-прототипу є однією з найважливіших концепцій, яку повинні знати фахівці JavaScript. Ця стаття дасть вам короткий огляд об’єкта Prototype на різних прикладах. Перш ніж читати цю статтю, вам потрібно буде базово розуміти thisпосилання на JavaScript.

Об’єкт-прототип

Для наочності розглянемо наступний приклад:

function Point2D(x, y) { this.x = x; this.y = y; }

Коли Point2Dфункція оголошена, prototypeдля неї буде створено властивість за замовчуванням з іменем (зауважте, що в JavaScript функція також є об'єктом). prototypeВластивість є об'єктом , який містить constructorвластивість і його значення Point2Dфункції: Point2D.prototype.constructor = Point2D. І коли ви телефонуєте Point2Dз newключовим словом, новостворені об'єкти успадкують усі властивості відPoint2D.prototype . Для того, щоб перевірити , що ви можете додати метод , названий moveв Point2D.prototypeнаступним чином :

Point2D.prototype.move = function(dx, dy) { this.x += dx; this.y += dy; } var p1 = new Point2D(1, 2); p1.move(3, 4); console.log(p1.x); // 4 console.log(p1.y); // 6

Point2D.prototypeНазивається прототип об'єкта або прототипу з p1об'єкта і для будь-якого іншого об'єкта , створеного з new Point2D(...)синтаксисом. Ви можете додати більше властивостей до Point2D.prototypeоб’єкта, як завгодно. Загальний шаблон - це метод оголошення, Point2D.prototypeа інші властивості будуть оголошені у функції конструктора.

Вбудовані об'єкти в JavaScript будуються подібним чином. Наприклад:

  • Прототип об'єктів, створених за допомогою синтаксису new Object()або .{}Object.prototype
  • Прототип масивів, створених за допомогою new Array()або []синтаксис, є Array.prototype.
  • І так далі з іншими вбудованими об’єктами, такими як Dateі RegExp.

Object.prototypeуспадковується усіма об'єктами і не має прототипу (його прототипом є null).

Ланцюжок прототипів

Механізм прототипу простий: коли ви отримуєте доступ до властивості pоб’єкта obj, механізм JavaScript шукатиме цю властивість усередині objоб’єкта. Якщо механізму не вдається здійснити пошук, він продовжує пошук у прототипі objоб'єкта і так до досягнення Object.prototype. Якщо після завершення пошуку і нічого не знайдено, результат буде undefined. Наприклад:

var obj1 = { a: 1, b: 2 }; var obj2 = Object.create(obj1); obj2.a = 2; console.log(obj2.a); // 2 console.log(obj2.b); // 2 console.log(obj2.c); // undefined

У наведеному вище фрагменті оператор var obj2 = Object.create(obj1)створить obj2об'єкт з obj1об'єктом- прототипом . Іншими словами, obj1стає прототипом obj2замість Object.prototypeза замовчуванням. Як бачите, bце не властивість obj2, ви все одно можете отримати до нього доступ через ланцюжок прототипів. Однак для cвластивості ви отримуєте undefinedзначення, оскільки його неможливо знайти в obj1та Object.prototype.

Заняття

У ES2016 ми тепер можемо використовувати Classключове слово, а також методи, згадані вище, для маніпулювання prototype. JavaScript Classзвертається до розробників із фонових технологій ООП, але, по суті, він робить те саме, що і вище.

class Rectangle { constructor(height, width) { this.height = height this.width = width } get area() { return this.calcArea() } calcArea() { return this.height * this.width } } const square = new Rectangle(10, 10) console.log(square.area) // 100

Це в основному те саме, що:

function Rectangle(height, width) { this.height = height this.width = width } Rectangle.prototype.calcArea = function calcArea() { return this.height * this.width }

Методи getterі setterв класах прив'язують властивість Object до функції, яка буде викликана при пошуку цієї властивості. Це просто синтаксичний цукор, який допомагає полегшити пошук або встановлення властивостей.

Більше інформації про прототипи JS:

  • Все, що вам потрібно знати, щоб зрозуміти прототип JavaScript