Как разрешение функций в цепочке прототипов будет работать для Object.prototype как конструктора

#javascript #constructor #prototype #prototype-chain

#javascript #конструктор #прототип #прототип-цепочка

Вопрос:

Я имею в виду этот веб-архив статьи, первоначально посвященной Helephant.com , чтобы узнать, как Javascript разрешает функции в цепочке прототипов при вызове объектов.

В статье приводятся цитаты,

Если у объекта нет метода, установленного непосредственно для него, javascript затем ищет функцию-конструктор, которая создала объект. Javascript проверяет свойство prototype конструктора для метода.

В следующем коде, если вы проверяете rufus.constructor глобальный Object() конструктор, JS будет напрямую проверять глобальный объект (), поскольку rufus.constructor Object() или согласно цитате из статьи выше, сначала он посмотрит на конструктор, а затем найдет свойство prototype и так далее.. Как JS разрешит функцию ( rufus.toString ) . Я совершенно сбит с толку этим.

   //PET CONSTRUCTOR
function Pet(name, species, hello)
 
  {   this.name = name;
      this.species = species;
      this.hello = hello; }
 
Pet.prototype = {
  sayHello : function(){
    alert(this.hello);
  }
}
 
//CAT CONSTRUCTOR
  function Cat(name, hello, breed, whiskerLength)
  {   this.name = name;
      this.hello = hello;
      this.breed = breed;
      this.whiskerLength = whiskerLength;}
  
Cat.prototype = new Pet();
var rufus = new Cat("rufus", "miaow", "Maine Coon", 7);

rufus.toString; 
  

Комментарии:

1. есть ли еще что-нибудь неясное?

Ответ №1:

Если у объекта нет метода, установленного непосредственно для него, javascript затем ищет функцию-конструктор, которая создала объект. Javascript проверяет свойство prototype конструктора для метода.

Формулировка сбивает с толку. JavaScript просматривает цепочку прототипов __proto__ и не использует constructor свойство. Они упомянули Constructor , потому что обычно именно так объекты получают свое свойство prototype — through Constructor.prototype . Но это не всегда так. Вы можете установить прототип следующим образом:

 var rufus2 = Object.create(new Pet());
Object.getPrototypeOf(rufus) === Object.getPrototypeOf(rufus2); // true
  

Относительно того, как toString решается метод:

                     rufus.hasOwnProperty('toString'); // false -> go up
(new Pet())         rufus.__proto__.hasOwnProperty('toString'); // false -> go up 
({sayHello :...})   rufus.__proto__.__proto__.hasOwnProperty('toString'); // false -> go up 
(Object.prototype)  rufus.__proto__.__proto__.__proto__.hasOwnProperty('toString'); // true 
  

Комментарии:

1. @Maximums, вы уверены, что JS фактически никогда не использует constructor свойство для поиска свойств / методов. Я хотел бы верить, что для этого не должно требоваться искать свойство конструктора, когда каждый объект имеет прямой указатель / путь (через proto ) к своему классу наследования, однако автор, ИМХО, достаточно осведомлен, судя по прочтению всех ее статей.

2. @Maximums, далее в этой статье говорится, что > В браузерах на базе Mozilla каждый объект предоставляет другое свойство, называемое proto , которое дает вам доступ к способу отслеживания браузером цепочки прототипов.

3. Означает ли это, что этот пост иллюстрирует 2 разных способа, используемых браузерами для разрешения свойств и методов. Браузеры на базе Mozilla через ( proto ) и другие браузеры (на основе IE и webkit), как она описала через constructor поиск свойств.

4. Далее на [ __proto__ странице] Mozilla ( developer.mozilla.org/en-US/docs/Web/JavaScript/Reference / … ) утверждает >> Только недавно свойство proto было стандартизировано в спецификации языка ECMAScript 6 для веб-браузеров>> значит ли это, что то, что она написала о поиске свойств / методов с использованием маршрута свойств ‘constructor’, она конкретно ссылается на более старыебраузеры без браузеров на базе Mozilla, т.Е. Все старые браузеры на базе IE и webkit.

5. обратите внимание, статья была очень старой, написанной на 17 Aug 09 .

Ответ №2:

 function Person () { }
Person.prototype.sayName = function () { };


var bob = new Person();
console.log(bob.sayName === Person.prototype.sayName); // true
console.log(bob.constructor.prototype.sayName === Person.prototype.sayName); // true
console.log(bob.__proto__.sayName === Person.prototype.sayName); // true


console.log(bob.constructor === Person); // true
console.log(bob.__proto__ === Person.prototype); // true
  

Это ваши отношения.
Если свойство / функция не может быть найдена для объекта, он поднимается по __proto__ цепочке, чтобы найти то, что он ищет. В старых браузерах __proto__ он был недоступен для разработчиков JS, но по-прежнему оставался объектом, который браузер / узел использовал за кулисами, чтобы ссылаться на свойство Constructor.prototype .

PS: старайтесь не использовать глубокую иерархию в JS. Это путь многих разрывов. Глубокие иерархии вызывают боль в других языках, основанных на классах, но являются проблемой в JS, где часто достаточно функции.

Комментарии:

1. Можете ли вы, пожалуйста, попытаться ответить в контексте кода, который я опубликовал, object ( rufus ) наследуется от object ( Cat.prototype = new Pet() ) другого типа ( Pet ), чей прототип Pet.prototype сам наследуется от global Object.prototype ( {} ) . В вашем коде объекты constructor и prototype довольно очевидны и мало помогают понять, где наследование в гораздо более сложных структурах наследования, как в моем случае.