Первым делом зачем беспокоиться.
Понимание сути помогает уму расслабиться, иначе он будет постоянно помнить, что за черная магия происходит. Наследование прототипов - это ядро ​​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> для вновь созданного объекта при запуске функции конструктора. Пожалуйста, дайте мне знать, если есть что улучшить. Хлопайте в ладоши, если это имеет смысл.