JavaScript является объектно-ориентированным языком и, согласно Wilkipedia:
Объектно-ориентированное программирование (ООП) — это парадигма программирования, основанная на концепции «объектов», которые могут содержать данные и код: данные в виде полей (часто известных как атрибуты или свойства), а код — в виде процедур (часто известных как методы).
Итак, давайте погрузимся в изучение объектов Javascript и их прототипов, создав простой объект.
Метод «message» был добавлен с помощью анонимной функции. «This» в методе используется для связи переменных внутри метода с объектом.
const object = {
user: "guest",
where: "dev.to",
message: function () {
console.log(`${this.user}, welcome to ${this.where}`)
}
}
console.log(object) // result from the console
// {user: 'guest', where: 'dev.to', message: ƒ}
// message: ƒ ()
// user: "guest"
// where: "dev.to"
// [[Prototype]]: Object
console.log(object.message()) // guest, welcome to dev.to
console.log(object.__proto__)// result from the console
//{constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, //hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
//constructor: ƒ Object()
//hasOwnProperty: ƒ hasOwnProperty()
//isPrototypeOf: ƒ isPrototypeOf()
//propertyIsEnumerable: ƒ propertyIsEnumerable()
//toLocaleString: ƒ toLocaleString()
//toString: ƒ toString()
//valueOf: ƒ valueOf()
//__defineGetter__: ƒ __defineGetter__()
//__defineSetter__: ƒ __defineSetter__()
//__lookupGetter__: ƒ __lookupGetter__()
//__lookupSetter__: ƒ __lookupSetter__()
//__proto__: (...)
//get __proto__: ƒ __proto__()
//set __proto__: ƒ __proto__()
Обратите внимание, что прототип объекта является свойством еще одного прототипа, а внутри этого прототипа может быть еще один прототип и так далее.
Получить прототип объекта можно и другим способом:
Object.getPrototypeOf(object)
Попробуем извлечь один из методов прототипа
console.log(object.hasOwnProperty()) // false
Работает!
Давайте добавим то же свойство к объекту и занесем его в console.log:
const object = {
user: "guest",
where: "dev.to",
message: function () {
console.log(`${this.user}, welcome to ${this.where}`)
},
hasOwnProperty : function () {
console.log("the method was added to the object")
}
}
console.log(object.hasOwnProperty()) // the method was added to the object
Таким образом, мы можем сделать предположение о порядке поиска в объекте:
- Сначала поиск в объекте
- После в прототипе объекта
- После в прототипе прототипа…
Как установить прототип:
- С помощью Object.create()
const objectWithProto = Object.create(object)
console.log(objectWithProto)// {} - empty object
console.log(objectWithProto.message()) // guest, welcome to dev.to - message method of prototype
console.log(objectWithProto.__proto__)// results from the console
//{user: 'guest', where: 'dev.to', message: ƒ}
//message: ƒ ()
//user: "guest"
//where: "dev.to"
//[[Prototype]]: Object
- С помощью конструктора
Создание конструктора
function User (user, where) {
this.user = user;
this.where = where
}
Создание метода для прототипа
const userPrototype = {
message () {
console.log(`${this.user}, welcome to ${this.where}`) }
}
Добавление метода к прототипу объекта
User.prototype = userPrototype;
Добавление конструктора пользователя в прототип (который принимает параметры из конструктора и которые могут быть переданы методу message в прототипе)
User.prototype.constructor = User;
console.log(User) // ƒ User (user, where) {
this.user = user;
this.where = where
}
console.log(User.__proto__) // ƒ () { [native code] }
Давайте проверим, что у нас получилось:
const myUser = new User('Julie Cherner', ‘dev.to - author’);
myUser.message() // Julie Cherner, welcome to dev.to - author
console.log(myUser) // User {user: 'Julie Cherner', where: 'dev.to - author'}
console.log(myUser.__proto__) // results from console
//{message: ƒ, constructor: ƒ}
//constructor: ƒ User(user, where)
//message: ƒ message()
//[[Prototype]]: Object
Итак, прототипы предоставляют большие возможности для наследования свойств объектов в Javascript.