问题
I am referring to this article on Helephant.com, to learn how Javascript resolves functions in the prototype chain when called on objects.
The article quotes,
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.
In the following code, if you check rufus.constructor is the global Object() constructor, so will JS directly check the global Object() since rufus.constructor is Object() or as per the article quote above it will first look at the constructor and then find the prototype property and so on.. How will JS resolve the function (rufus.toString). I am quite confused with this.
//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:
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.
The wording is confusing. The JavaScript looks up the prototype chain through __proto__ and does not use constructor property. They mentioned Constructor because usually, that is how objects get their prototype - through Constructor.prototype property. But that is not always true. You can set the prototype like this:
var rufus2 = Object.create(new Pet());
Object.getPrototypeOf(rufus) === Object.getPrototypeOf(rufus2); // true
Regarding how the toString method is resolved:
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
回答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
Those are your relationships.
If a property / function can not be found on an object, it goes up the __proto__ chain to find what it's looking for. In older browsers, __proto__ was not accessible to JS devs, but was still the object that the browser/Node used behind the scenes, to refer to the Constructor.prototype property.
PS: try not to use deep hierarchy in JS. That is a path of many tears. Deep hierarchies cause pain in other class-based languages, but are misery in JS, where often a function would suffice.
来源:https://stackoverflow.com/questions/40013207/how-function-resolution-in-prototype-chain-will-work-for-object-prototype-as-con