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 theprototype: 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 constructorprototypevalue
    • The prototype object is the parent of the current instance object
  • 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

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.

  1. Function prototype properties (figure)
    • Each function has oneprototypeProperty, which by default points to oneThe Object empty Object(Called: prototype object)
    • There is a property in the stereotype objectconstructor, which points to the function object
  // 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

  1. 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

  1. Each function has oneprototype, i.e.,Explicit stereotypes (attributes)
  2. One for each instance object__proto__And what might be calledImplicit stereotypes (attributes)
  3. The implicit stereotype of an object is the explicit stereotype of its corresponding constructor
  4. Memory structure (graph)
  5. Conclusion:
  • Function of theprototypeProperty: 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

  1. Prototype chain (diagram)
  • When accessing an object’s properties,
    • In the firstIts propertiesFind, return
    • If not, go along again__proto__The chain looks up, finds and returns
    • If not found, return undefined
  • Alias: Implicit prototype chain
  • Function: Find an object’s properties (methods)
  1. Constructor/prototype/solid Object relationships (diagram)
  2. Constructor/Prototype/Solid Object relationship 2

  1. We can use object’shasOwnProperty()To check theThe object itselfWhether the attribute is contained in;
  2. useinWhen 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

  1. readObject property value: is automatically looked up in the prototype chain
  2. setWhen 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
  3. 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 prototypeprototypeObject 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