Прототипи
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
харесва на разработчици от OOP фонове, но по същество прави същото като по-горе.
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
and и setter
в класовете обвързват свойство Object към функция, която ще бъде извикана, когато се търси това свойство. Това е просто синтактична захар, която помага да се улесни търсенето или задаването на свойства.
Повече информация за JS прототипи:
- Всичко, което трябва да знаете, за да разберете прототипа на JavaScript