Describe the prototype chain
background
JavaScript is dynamic and does not provide an implementation of class itself. Even if the class keyword is introduced in ES2015/ES6, it is only a syntax sugar, and JavaScript is still based on the prototype
When it comes to inheritance, JavaScript has only one structure: objects. Each instance object has a private property (called proto) that points to the prototype of its constructor. The prototype object also has its own prototype object (_proto_), Layer up until the prototype object of an object is null. By definition, null has no prototype and is the last link in the prototype chain.
Almost all objects in JavaScript are instances of objects at the top of the prototype chain.
Link: https://developer.mozilla.org...
Let's start with a few noun concepts
- Prototype explicit prototype
- proto implicit prototype
Introduce the following reference types
- All have object properties, so you can freely extend attributes.
- There is an implicit prototype proto attribute, and the attribute value is an ordinary object.
- Implicit prototype__ proto__ The property value of points to the property value of the explicit prototype prototype of its constructor.
- When obtaining a property of an object, if the object itself does not have this property, its implicit prototype will be removed__ proto__ (that is, the explicit prototype of its constructor).
Look 🌰
function Student(name) { this.name = name } const stu = new Student('xiaomin') stu.name // 'xiaomin' // toString is a common method of an object and returns a string representing the object stu.toString() // '[object Object]' // Assign value to toString stu.prototype.toString = function stuToString() { return `${this.name}`; }; console.log(stu.toString()); // expected output: "Gabby"
Question: why can stu get toString without defining it at first?
The stu instance starts from itself and finds that there is no toString method. If you can't find it, go up and find the prototype attribute of the Student constructor, but you still can't find it. Since the prototype # of the constructor is an Object, and the constructor of that Object is Object, Object is found ToString method under prototype.
Here is a supplementary note. If it is not found in the end, it returns undefined. And object The implicit prototype of prototype points to null
tips: null is set to avoid dead loops
stu.xx // undefined
Extend a concept: instanceof
The instanceof operator is used to detect whether the prototype attribute of the constructor appears on the prototype chain of an instance object
function Car(make, model, year) { this.make = make; this.model = model; this.year = year; } const auto = new Car('Honda', 'Accord', 1998); console.log(auto instanceof Car); // expected output: true console.log(auto instanceof Object); // expected output: true
instabceof implementation mode (principle)
// The prototype of variable R exists in the prototype chain of variable L function instance_of (L, R) { // If the validation is a basic data type, it will directly return false const baseType = ['string', 'number', 'boolean', 'undefined', 'symbol'] if(baseType.includes(typeof(L))) { return false } let RP = R.prototype; // Take the display prototype of R L = L.__proto__; // Take the implicit prototype of L while (true) { if (L === null) { // Find the top layer return false; } if (L === RP) { // Strict equality return true; } L = L.__proto__; // Not found. Continue to look up the prototype chain } }
The instanceof judgment process is as follows:
- Implicit prototype of f +__ proto__ And foo Prototype is equal, so it returns true.
- Implicit prototype of f +__ proto__ , and object Prototype # doesn't wait, so keep going up. Implicit prototype of f +__ proto__ Point to foo Prototype, so continue to use foo prototype.__ proto__ To compare object Prototype, return true after judging the equality. (because Foo.prototype , is an ordinary object)
Reference link: https://juejin.cn/post/693449...