原型链中的函数解析如何适用于 Object.prototype 作为构造函数

How function resolution in prototype chain will work for Object.prototype as constructor

我指的是 this web archive of an article originally on Helephant.com,以了解 Javascript 如何在调用对象时解析原型链中的函数。

文章引用,

If the object doesn’t have the method set directly on it, javascript then looks for a Constructor function that created the object. Javascript checks the constructor’s prototype property for the method.

在下面的代码中,如果检查rufus.constructor是全局的Object()构造函数,那么JS会直接检查全局的Object(),因为rufus.constructorObject()或者按照上面的文章引用,它会首先查看构造函数,然后找到原型 属性 等等。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; 
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__ 链向上查找它要查找的内容。在较旧的浏览器中,JS 开发人员无法访问 __proto__,但仍然是 browser/Node 在幕后使用的对象,以引用 Constructor.prototype 属性.

PS:尽量不要在JS中使用深层次。那是一条泪流满面的路。深层次结构在其他基于 class 的语言中会造成痛苦,但在 JS 中却很痛苦,通常一个函数就足够了。

If the object doesn’t have the method set directly on it, javascript then looks for a Constructor function that created the object. Javascript checks the constructor’s prototype property for the method.

措辞令人困惑。 JavaScript通过__proto__查找原型链,使用constructor属性。他们提到 Constructor 是因为通常情况下,对象就是通过 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