Първо, първо, защо да се притеснявате.
Разбирането на сърцевината помага на ума да приема нещата по-лесно, в противен случай той продължава да се носи в ума си какъв вид черна магия се случва. Наследяването на прототипи е основното нещо на javascript, където се случва по-голямата част от магията. Класовете не са просто синтетична захар върху „Прототипно наследяване“ за подробности четенено в крайна сметка той използва наследяването на прототипа . Класовете го правят по-четлив, вместо да използват старомодно ръчно създаване на прототипи. Тази публикация ще обсъди основната концепция зад класовете в JavaScript.

нека започнем, като демистифицираме какво представляват свойствата прототип и __proto__.
Всяка функция на JavaScript (известна също като функции на конструктора) има прототипсвойство, което се използва за създаване на __proto__ свойство на обекти. Това__proto__еобектът, който след това се използва във веригата за търсене.

Можете да проверите кой прототип се използва за създаване на обекта.

Object.prototype.isPrototypeOf({}) // true
Function.prototype.isPrototypeOf(()=>{}) // true

това означава, че ({}).__proto__ === Object.prototype всеки обект има достъпни за него свойства и методи, които са достъпни на Object, откъдето идват toString и много други функции на вашия обект, същият е случаят с (()=>{}).__proto__ === Function.prototype сега, тъй като функцията е също екземпляр на Object, така че 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`)
}

Ключовата бележка тук всяка функция има свойство прототип, което й е присвоено, което е обект, този обект има свойство, наречено конструктор, което е свързано обратно към оригиналната функция, това е важно при настройването на това (ще обсъдим в отделна публикация). Всеки път, когато се използва нова ключова дума във функцията конструктор, тя ще създаде нов обект и ще използва прототипа на функцията конструктор като __proto__ на новосъздадения обект (ще обсъдим скоро как става това използван при наследяване заедно с Object.create скоро ) като прототип е обект, към който можем да прикачваме функции/свойства. Object.create се използва за прилагане на наследяване. Според Уеб документи на MDN

Методът Object.create() създава нов обект, като използва съществуващ обект като прототип на новосъздадения обект.

Лесно е да се запомни, ако го приемем като ' Методът Object.create() създава нов обект и задава предоставения обект като свойство __proto__ на новосъздадения обект, това е втората основна разлика между Object.create и нова ключова дума. Това свойство __proto__ се използва под капака, за да запази нещата непокътнати. Помислете за следното.

function Programmer({skills}){
 this.skills = skills
}

Това ще има същата структура като по-горе със свойството прототип с конструктор, сочещ обратно към функцията. Тук имаме цел да разширим Programmer от Human. Така че номерът е да актуализираме свойството прототип, имаме две опции

1- Programmer.prototype = new Human({ name:’a’, age:31 });

2- Programmer.prototype = Object.create(Human.prototype);

Като просто го разгледаме, можем да кажем, че 1-вата опция няма много смисъл (Тя наистина ни дава достъп до функции, които са налични на прототипа на Human), така че ще отидем с втората опция, оставяйки обекта на бъде инициализирано по-късно,Object.createще създаде нов обект и всичко, което е в Human.prototype, ще бъде налично в __proto__ свойството на този новосъздан обект. Сега Programmer.prototype.__proto__ === Human.prototype е валиден. Ще добавим един метод на Programmer.

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.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, той ще отпечата 'функция' помните конструкторската функция?. Третата разлика е начинът, по който ключовата дума new задава this за новосъздадения обект, докато изпълнява функцията конструктор. Моля, уведомете ме, ако има нещо за подобряване. Пляскайте, ако има смисъл.