Prototype and prototype chain
- All functions have a special property:
prototype
: Explicit stereotype property
- All instance objects have a special property:
__proto__
: Implicit stereotype property
- The relationship between explicit and implicit archetypes
- Function of the
prototype
: is automatically assigned when a function is defined. The default value is {}, which is used as a prototype object - Instance object
__proto__
: is automatically added when the instance object is created and assigned to the constructorprototype
value - The prototype object is the parent of the current instance object
- Function of the
- Prototype chain
- All instance objects have it
__proto__
Property, which points to the prototype object - So through
__proto__
Properties form a chain structure —-> prototype chain - When looking for properties/methods inside an object, the JS engine automatically looks along the prototype chain
- The stereotype chain is not used when assigning values to object properties, but only in the current object
- All instance objects have it
Prototype prototype
In JavaScript, whenever you define a function datatype (plain function, class), you are born with a prototype property that points to the function’s prototype object and is the value of an object datatype.
- Function prototype properties (figure)
- Each function has one
prototype
Property, which by default points to oneThe Object empty Object
(Called: prototype object) - There is a property in the stereotype object
constructor
, which points to the function object
- Each function has one
// Each function has a prototype attribute, which by default points to an empty Object.
console.log(Date.prototype, typeof Date.prototype)
function Fun () {// Alt + shift +r(rename)
}
console.log(Fun.prototype) // Default points to an empty Object (without our attributes)
// The prototype object has a property constructor that points to the function object
console.log(Date.prototype.constructor===Date)
console.log(Fun.prototype.constructor===Fun)
Copy the code
- Add attributes to the prototype object (usually methods)
- Action: All instance objects of a function automatically have properties (methods) in the stereotype
// Add attributes (usually methods) to the prototype object ===> The instance object is accessible
Fun.prototype.test = function () {
console.log('test()')}var fun = new Fun()
fun.test()
Copy the code
Display stereotypes and implicit stereotypes
- Each function has one
prototype
, i.e.,Explicit stereotypes (attributes) - One for each instance object
__proto__
And what might be calledImplicit stereotypes (attributes) - The implicit stereotype of an object is the explicit stereotype of its corresponding constructor
- Memory structure (graph)
- Conclusion:
- Function of the
prototype
Property: Automatically added when a function is defined. The default value is an empty Object - The object’s
__proto__
Property: Automatically added when the object is created, default to the constructor’s Prototype property value - Programmers can directly manipulate explicit stereotypes, but not implicit stereotypes (prior to ES6)
// Define the constructor
function Fn() { // internal statement: this.prototype = {}
}
// 1. Each function has an explicit prototype attribute, which by default points to an empty Object
console.log(Fn.prototype)
// 2. Each instance object has a __proto__, which can be called an implicit prototype
// Create an instance object
var fn = new Fn() // Internal statement: this.__proto__ = fn.prototype
console.log(fn.__proto__)
// 3. The implicit stereotype of an object is the explicit stereotype of its corresponding constructor
console.log(Fn.prototype===fn.__proto__) // true
// Add methods to the prototype
Fn.prototype.test = function () {
console.log('test()')}// Call the methods of the prototype through the instance
fn.test()
Copy the code
constructor
Each stereotype has a constructor property that points to the association’s constructor.
function Person() {}console.log(Person===Person.prototype.constructor) //true
var person = new Person();
console.log(person.__proto__ == Person.prototype) // true
console.log(Person.prototype.constructor == Person) // true
Copy the code
Prototype chain
In JavaScript everything is an object, and objects have relationships with each other, not in isolation. In JavaScript, the inheritance relationship between objects is that the prototype Object points to the parent Object until it points to the Object Object. In this way, a prototype pointing chain is formed. The technical term is called prototype chain.
Example: Person → Person → Object, ordinary people inherit human, human inherit Object class
- Prototype chain (diagram)
- When accessing an object’s properties,
- In the first
Its properties
Find, return - If not, go along again
__proto__
The chain looks up, finds and returns - If not found, return undefined
- In the first
- Alias: Implicit prototype chain
- Function: Find an object’s properties (methods)
- Constructor/prototype/solid Object relationships (diagram)
- Constructor/Prototype/Solid Object relationship 2
- We can use object’s
hasOwnProperty()
To check theThe object itself
Whether the attribute is contained in; - use
in
When checking whether an object contains a property, if there is no but in the objectIn the prototype
, also returns true
function Person() {}
Person.prototype.a = 123;
Person.prototype.sayHello = function () {
alert("hello");
};
var person = new Person()
console.log(person.a)/ / 123
console.log(person.hasOwnProperty('a'));//false
console.log('a'in person)//true
Copy the code
// console.log(Object)
//console.log(Object.prototype)
console.log(Object.prototype.__proto__)
function Fn() {
this.test1 = function () {
console.log('test1()')}}console.log(Fn.prototype)
Fn.prototype.test2 = function () {
console.log('test2()')}var fn = new Fn()
fn.test1()
fn.test2()
console.log(fn.toString())
console.log(fn.test3)
// fn.test3()
Copy the code
/* 1. The display prototype of the function points to an empty instance Object by default (Object does not satisfy this requirement) */
console.log(Fn.prototype instanceof Object) // true
console.log(Object.prototype instanceof Object) // false
console.log(Function.prototype instanceof Object) // true
/* all functions are instances of Function (including Function) */
console.log(Function.__proto__===Function.prototype)
/* the prototype Object is the end of the prototype chain */
console.log(Object.prototype.__proto__) // null
Copy the code
Prototype chain attribute problem
read
Object property value: is automatically looked up in the prototype chainset
When setting the property value of an object: The prototype chain is not searched. If the property does not exist in the current object, the property is added and its value is set- Methods are defined in stereotypes, and properties are defined on the object itself via constructors
function Fn() {
}
Fn.prototype.a = 'xxx'
var fn1 = new Fn()
console.log(fn1.a, fn1) // xxx, Fn{}
var fn2 = new Fn()
fn2.a = 'yyy'
console.log(fn1.a, fn2.a, fn2) // xxx , yyy , Fn{a:'yyy'}
function Person(name, age) {
this.name = name
this.age = age
}
Person.prototype.setName = function (name) {
this.name = name
}
var p1 = new Person('Tom'.12)
p1.setName('Bob')
console.log(p1) //Person {name: "Bob", age: 12}
var p2 = new Person('Jack'.12)
p2.setName('Cat')
console.log(p2) //Person {name: "Cat", age: 12}
console.log(p1.__proto__===p2.__proto__) // true
Copy the code
instanceof
1. How is instanceof judged?
- A instanceof B
- Is the object on the left an instance of the type on the right
- If B function is explicit prototype
prototype
Object in the implicit prototype chain of object A__proto__
On, return true, otherwise return false
2. The handwritten instanceof
function myInstanceOf(a,b){
let left = a.__proto__;
let right = b.prototype;
while(true) {if(left == null) {return false
}
if(left == right){
return true
}
left = left.__proto__
}
}
Copy the code
3. Function is a self-generated instance of new
function Foo() {}var f1 = new Foo()
console.log(f1 instanceof Foo) // true
console.log(f1 instanceof Object) // true
Copy the code
console.log(Object instanceof Function) // true
console.log(Object instanceof Object) // true
console.log(Function instanceof Function) // true
console.log(Function instanceof Object) // true
function Foo() {}
console.log(Object instanceof Foo) // false
Copy the code
practice
function A () {
}
A.prototype.n = 1
var b = new A()
A.prototype = {
n: 2.m: 3
}
var c = new A()
console.log(b.n, b.m, c.n, c.m) //1 undefined 2 3
Copy the code
function F (){}
Object.prototype.a = function(){
console.log('a()')}Function.prototype.b = function(){
console.log('b()')}var f = new F()
f.a() //a()
f.b() // If not found, an error will be reported
F.a()
F.b()
console.log(f)
console.log(Object.prototype)
console.log(Function.prototype)
Copy the code