Первым делом зачем беспокоиться.
Понимание сути помогает уму расслабиться, иначе он будет постоянно помнить, что за черная магия происходит. Наследование прототипов - это ядро javascript, в котором происходит большая часть волшебства. Классы - это не просто синтетический сахар поверх Прототипного наследования для деталей читать, но, в конце концов, он использует наследование прототипа. . Классы делают его более читабельным, вместо того, чтобы использовать старомодное ручное прототипирование. В этом посте будет обсуждаться основная концепция, лежащая в основе классов в JavaScript.
давайте начнем с того, что проясним, что такое свойства prototype и __proto__.
Каждая функция javascript (также известная как функции конструктора) имеет prototype, которое используется для создания свойства __proto__ для объектов. Этот __proto__ является объектом, который затем используется в поисковой цепочке.
Вы можете проверить, какой прототип используется для создания объекта.
Object.prototype.isPrototypeOf({}) // true Function.prototype.isPrototypeOf(()=>{}) // true
это означает, что ({}).__proto__ === Object.prototype
любой объект имеет свойства и методы, доступные для него, которые доступны в Object, откуда toString и многие другие функции берутся из вашего объекта, то же самое в случае (()=>{}).__proto__ === Function.prototype
сейчас, поскольку функция также экземпляр объекта, поэтому Object.prototype.isPrototypeOf(Function)
также верно. Мы обсуждали это, потому что и new, и Object.create используются для создания и инициализации нового объекта с прикрепленным к нему свойством __proto__, но по-разному. .
В более легкой заметке основное различие между new и Object.create заключается в том, что для new нам нужна функция-конструктор, а для Object.create мы используем объекты для создания нового объекта. посмотрим, что говорят веб-документы MDN о новом ключевом слове.
Оператор
new
позволяет разработчикам создать экземпляр определенного пользователем типа объекта или одного из встроенных типов объектов, который имеет функцию конструктора.
Учти это.
function Human({ name, age }){ this.name = name; this.age = age; } Human.prototype.getInfo= function(){ console.log(`human ${this.name} is ${this.age} year old`) }
Ключевым моментом здесь является то, что каждой функции присваивается свойство прототип, которое представляет собой объект, у которого есть свойство, называемое конструктором, которое связано с исходной функцией. Это важно при настройке this (обсудим в отдельном посте). Всякий раз, когда новое ключевое слово используется в функции конструктора, оно создает новый объект и использует прототип функции конструктора как __proto__ вновь созданного объекта (вкратце мы обсудим, как это используется в наследовании вместе с Object.create в ближайшее время), поскольку прототип - это объект, к которому мы можем прикреплять функции / свойства. Object.create используется для реализации наследования. Согласно веб-документы MDN
‘ Метод
Object.create()
создает новый объект, используя существующий объект в качестве прототипа вновь созданного объекта. ’
Легко запомнить, если мы примем это как «Метод Object.create()
создает новый объект и устанавливает предоставленный объект как свойство __proto__ для вновь созданного объекта, что является вторым основным отличием между Object.create и новое ключевое слово. Это свойство __proto__ используется для сохранения целостности вещей. Рассмотрим следующее.
function Programmer({skills}){ this.skills = skills }
Он будет иметь ту же структуру, что и выше, со свойством prototype, имеющим конструктор, указывающий на функцию. Здесь у нас есть цель расширить Programmer от Human. Итак, уловка состоит в том, чтобы обновить свойство prototype, у нас есть два варианта
1- Programmer.prototype = new Human({ name:’a’, age:31 });
2- Programmer.prototype = Object.create(Human.prototype);
Просто изучив его, мы можем сказать, что 1-й вариант не имеет особого смысла (он дает нам доступ к функциям, доступным в прототипе Human), поэтому мы выберем второй вариант, оставив объект на будет инициализирован позже, Object.create
создаст новый объект, и все, что находится в Human.prototype
, будет доступно на __proto__
property этого вновь созданного объекта. Сейчас Programmer.prototype.__proto__ === Human.prototype
действительно. Мы добавим один метод в Программист.
function Programmer({name,age,skill}){ this.skill = skill Human.call(this,{name,age}) } Programmer.prototype = Object.create(Human.prototype) Programmer.prototype.getGirl = function(){ console.log(`No you don't`) }
Мы вызвали Human просто для того, чтобы привязать свойства Human к этой области действия Programmer. Ниже приводится визуальное представление.
let obj = new Programmer({name:’zoomi’,age:31,skill:’javascript’})
У нас есть объект, который имеет доступ к своим родительским свойствам и методам Human. Изучить подписки
Human.prototype.isPrototypeOf(Programmer.prototype) //true
Human.prototype.isPrototypeOf(obj) // true
Все это можно сделать в ES6 следующим образом.
class Human { constructor({name,age}){ this.name = name; this.age = age; } getInfo= function(){ console.log(`human ${this.name} is ${this.age} year old`) } } class Programmer extends Human{ constructor({name,age,skill}){ super({name,age}) this.skill = skill } getGirl = function(){ console.log('no you don\'t') } }
Даже сейчас, если вы попытаетесь использовать typeof Human
в консоли, он напечатает 'function' / em> для вновь созданного объекта при запуске функции конструктора. Пожалуйста, дайте мне знать, если есть что улучшить. Хлопайте в ладоши, если это имеет смысл.