Почему обычные объекты в Javascript не имеют доступа к свойству prototype, и почему нам всегда нужно использовать __proto__?

Вопрос или проблема

предположим, что это мой фрагмент кода

let myHeroes = ["тор", "человек-паук"];

let heroPower = {
    тор: "молот",
    человек-паук: "паутина",
    getSpiderPower: function () {
        console.log(`сила паука равна ${this.человек-паук}`);
    }
};

heroPower.getSpiderPower();

heroPower.__proto__.getThorPower = function () {
    return `сила тора равна ${heroPower.тор}`;
};

heroPower.getThorPower();

Теперь, поскольку обычные объекты в JavaScript не имеют доступа к прототипу, чтобы добавить эту функциональность к объекту heroPower, мне действительно нужно писать __proto__ после имени объекта, чтобы добавить свойства, или есть другой простой способ?

Я пытался использовать heroPower.prototype.getThorPower=function(){..}, но это вызвало ошибку. Я ожидаю добавить функцию getThorPower внутри объекта heroPower, не определяя эту функцию явно внутри объекта, вставляя ее снаружи объекта.

Ответ или решение

Почему обычные объекты в JavaScript не имеют доступа к свойству prototype и необходимость использовать proto

Согласно спецификации JavaScript, объекты являются основой объектно-ориентированного программирования в этом языке. Однако между обычными объектами, созданными с помощью литералов или конструктора объекта, и функциями существует фундаментальное различие. В частности, обычные объекты не имеют свойства prototype и несколько отличаются в своих возможностях в отношении наследования и расширения функциональности.

Обычные объекты и свойство prototype

  1. Отсутствие prototype у объектов:
    Обычные объекты в JavaScript, такие как ваш объект heroPower, имеют внутреннее свойство, называемое [[Prototype]], но не имеют доступа к свойству prototype. Это свойство доступно только для функций, создаваемых с помощью конструктора. В результате, поэтому у обычных объектов нет возможности напрямую добавлять методы в prototype, и они не могут быть унаследованы другими объектами.

  2. Использование proto для доступа к прототипу:
    Чтобы добавить методы или свойства в прототип обычного объекта, вам необходимо обращаться к его встроенному прототипу через __proto__. В вашем примере:

    heroPower.__proto__.getThorPower = function () {
       return `thor power is ${heroPower.thor}`;
    };

    Данная конструкция работает, так как heroPower.__proto__ указывает на объект-прототип, который расширяется для включения нового метода getThorPower.

Как использовать prototype правильно

Проблема использования prototype с обычными объектами заключается в том, что:

  • Конструкторы: Для создания объекта с доступом к prototype, следует использовать функцию-конструктор. Например:

    function HeroPower() {
       this.thor = "hammer";
       this.spiderman = "sling";
    }
    
    HeroPower.prototype.getThorPower = function() {
       return `thor power is ${this.thor}`;
    };
    
    let heroPower = new HeroPower();
    console.log(heroPower.getThorPower());
  • Классическая и современная парадигма: В современном JavaScript (с ES6 и выше) вы также можете использовать синтаксис классов, который автоматически создает prototype для экземпляров:

    class HeroPower {
       constructor() {
           this.thor = "hammer";
           this.spiderman = "sling";
       }
    
       getThorPower() {
           return `thor power is ${this.thor}`;
       }
    }
    
    let heroPower = new HeroPower();
    console.log(heroPower.getThorPower());

Заключение

Таким образом, использование __proto__ является единственным способом добавления методов к прототипу обычного объекта, поскольку сами объекты не имеют свойства prototype. Однако помимо этого существует альтернатива: использование функций-конструкторов или классов, которые предоставляют возможность создания объектов с наследуемыми свойствами и методами. Это не только более чистый и поддерживаемый подход, но и спецификация JavaScript способствует созданию иерархии, что позволяет создавать более сложные структуры и аин исчерпывающе вести работу с объектами.

Оцените материал
Добавить комментарий

Капча загружается...