This article starts with the prototype diagram directly, and if you don’t clear up some concepts, you can look at it in the following sections
1. Diagram the prototype chain
1.1 “Iron Triangle” (Key points)
function Person() {};
var p = new Person();Copy the code
This diagram describes the relationship among constructors, instance objects, and stereotypes, which is the basis of the stereotype chain: (1) Instance objects are generated by the constructor new; (2) Both the constructor’s stereotype property and the instance object’s stereotype object point to the stereotype. (3) The stereotype object has a property constructor that points to the corresponding constructor
Prototype description: Instance objects can access properties and method validations with different names in Person.prototype:
p instanceof Person; // true
p.__proto__ === Person.prototype; // true
Person.prototype.constructor === Person; // trueCopy the code
1.2 Use prototypes as constructors
Prototype chain: p –> Person. Prototype –> Object. Prototype –> null It also has prototype objects that point to object.__proto__ (2) Since the prototype of the constructor’s prototype is also an Object, therefore: it also has prototype objects that point to null (special case) validation:
p instanceof Person; // true
p instanceof Object; // true
Person.prototype instanceof Object; // trueCopy the code
1.3 In-depth study leads to the Function constructor
1. Prototype Chain 1: See prototype in 1.2
Person –> Function. Prototype –> Object –> null Person = new Function(); Person –> prototype (); Function. Prototype = new Object();
Person instanceof Function; // true
Person instanceof Object; // true
Function.prototype instanceof Object; // trueCopy the code
Prototype –> Function –> Object –> null Function = new Function(); Function –> function.prototype
Function = new Function() = new Function()
Function.__proto__ === Function.prototype; // true
Function instanceof Function; // true
Function instanceof Object; // trueCopy the code
1.4 Complete prototype chain
It is added in the diagramObject = new Function()
The logic of the
Validation:
Object instanceof Function; // trueCopy the code
(2) All functions are instances of Function. (3) The end of all prototype chains points to Object.prototype
Here are some questions: (1) How many prototype chains are there in the picture above? (2) How to verify inheritance on the prototype chain at the code level? (See section 4) (3) How many “iron triangles” are there in the picture? List them separately
2. Prototype chain rewriting (emphasis)
When the instance object is created, its stereotype chain is already determined, and when the corresponding stereotype attribute points to change, it cannot change the stereotype chain
Person = function(options) { name: options.name, age: options.age }; Var p1 = new Person(); Person.prototype.sayName = function() {console.log(this.name); } // Person. Prototype. SayHi = function() {// p2 = new Person();Copy the code
Prototype link p1 and p2 have the same prototype chain, except for the difference in method calls. P2 has added prototype attributes (methods), p1 does not, and the prototype chain is P1 (p2) –> person.prototype –> object.prototype
Person = function(options) { name: options.name, age: options.age }; Var p1 = new Person(); Prototype = {sayName: function() {console.log(this.name); Var p2 = new Person();Copy the code
Rewriting the prototype object changes the prototype chain of the instance object, as shown below:
But why did p1’s archetypal chain not change and P2’s?
When the instance object is created, its prototype chain has been determined. When the corresponding prototype attribute points to change, it cannot change the prototype chain. The prototype chain is centered on the instance object and cannot be misled by the change of the prototype object
Overriding a prototype object is often used in prototype chain inheritance!!
3. Objects and Functions (emphasis)
Now, if we look at this, we might not be able to tell the difference between a function and an object, so think about it for 30 seconds, what is the relationship between a function and an object?
Official definition: In Javascript, every function is actually a function object
function fn() {};
var obj = {};
fn instanceof Object; // true
fn instanceof Function; // true
obj instanceof Object; // true
obj instanceof Function; // falseCopy the code
Prototype: fn –> Function. Prototype –> Object. Prototype: obj –> Object
In terms of function definitions: in javascript all functions are actually function objects, but objects are not necessarily functions
Function instanceof Object; // true
Object instanceof Function; // true
Function instanceof Function; // trueCopy the code
If you want to create a prototype, you can create a prototype. If you want to create a prototype, you can create a prototype. If you want to create a prototype, you can create a prototype. Object –> Function.prototype –> Object.prototype
Since both Function and Object are constructors, the new Function() method is called in the built-in Object
Conclusion: (1) Functions must be objects, but objects need not be functions. (2) Objects are created by functions
Prototype: fn –> Function. Prototype –> object. prototype obj –> object. prototype
The second point can be verified as follows:
var obj = { a: 1, b: 2} var arr = [2, 'foo', Var obj = new Object() obj.a = 1 obj.b = 2 var arr = new Array() arr[0] = 2 arr[1] = 'foo' arr[2] = false //typeof Object === 'function' //typeof Array === 'functionCopy the code
4. A few definitions
4.1 Definition and function of prototype
function Person() {};
var p = new Person();Copy the code
The prototype property of the constructor (person.prototype), also known as the prototype of the instance object created by calling the constructor (P.__proto__).
-
Any function has a prototype property, that is, a function’s prototype property. (Since objects are created by functions, objects also have prototype properties.)
-
The function’s prototype property is also an object (thus, this object also has a corresponding Prototype property)
-
Objects created by constructors link to this property of their constructors by default.
-
The prototype property of the constructor implements data sharing (inheritance).
4.2 Terms
The instance object has an attribute called __proto__, which is a nonstandard attribute that points to the constructor’s prototype attribute
Prototype the prototype object of the person. prototype constructor’s prototype attribute p.__proto__ Instance object
The stereotype property of a constructor is the same thing as the stereotype of an instance object, but it is accessed from a different perspective
5. Attribute search principle and attribute source judgment
5.1 Principles of Attribute Search (Key points)
Whenever code reads a property of an object, it performs a search for the property with the given name. The search starts with the object instance itself. If an attribute with a given name is found in the instance, the value of that attribute is returned. If not, search continues for the prototype object to which the pointer points, looking for the property with the given name in the prototype object. If the property is found in the prototype object, the property is returned. If not, the property is searched in the prototype object until the property is found, otherwise undefined is returned
In short, the property search principle is to look for attributes along the prototype chain of an object and return the most recent attribute
function Person(){} Person.prototype.name = "Nicholas"; Person.prototype.age = 29; Person.prototype.job = "Software Engineer"; Person.prototype.sayName = function(){ alert(this.name); }; var person1 = new Person(); var person2 = new Person(); person1.name = "Greg"; alert(person1.name); //"Greg" comes from instance alert(person2.name); //"Nicholas" comes from the prototypeCopy the code
Again, this is the principle of attribute masking
// Follow the example above delete person1.namel; alert(person1.name); // "Nicholas" comes from the prototypeCopy the code
5.2 hasOwnProperty() method and in operator
The hasOwnProperty() method detects whether a property exists in an instance or in a stereotype, and returns true only if the given property exists in an object instance
function Person(){} Person.prototype.name = "Nicholas"; Person.prototype.age = 29; Person.prototype.job = "Software Engineer"; Person.prototype.sayName = function(){ alert(this.name); }; var person1 = new Person(); var person2 = new Person(); alert(person1.hasOwnProperty("name")); //false person1.name = "Greg"; alert(person1.name); //"Greg" comes from instance alert(person1.hasownProperty ("name")); //true alert(person2.name); //"Nicholas" comes from the prototype alert(person2.hasownProperty ("name")); //false delete person1.name; alert(person1.name); //"Nicholas" comes from the prototype alert(person1.hasownProperty ("name")); //falseCopy the code
There are two ways to use the IN operator: alone and in for-in loops. When used alone, the IN operator returns true if a given property is accessible through an object, whether it exists in an instance or stereotype
Therefore, using both the hasOwnProperty() and in operators, you can determine whether an attribute exists in an object or a stereotype
function hasPrototypeProperty(object, name){ return ! object.hasOwnProperty(name) && (name in object); }Copy the code
By the way, since the IN operator looks for attributes throughout the prototype chain, for performance reasons, it is recommended to add another layer of judgment when using for-in loops
function Person(){} Person.prototype.name = "Nicholas"; Person.prototype.age = 29; var p = new Person(); p.sex = "fale"; for(key in p) { console.log(key); For (key in p) {if(p.hasownProperty (key)) {console.log(key); for(key in p) {if(p.hasownProperty (key)) {console.log(key); // Sex blocks attributes in the prototype}}Copy the code
5.3 Instanceof operator
Instanceof is used to determine if the object pointed to by the constructor’s prototype property is on the prototype chain of another object to be tested
For A instanceof B, it follows the __proto__ line and B’s prototype line, and returns true if both lines can find the same reference, i.e., the same object. Return false if the ends are not found yet. It doesn’t matter if you don’t understand, the following will be combined with legend analysis
function Person() {} var p = new Person(); console.log(p instanceof Object); //true console.log(p instanceof Person); //trueCopy the code
Javascript Advanced Programming Notes: Creating objects Next: javascript Advanced Programming Notes: Inheritance
Understand JavaScript prototype object and prototype chain inheritance and prototype chain