Js constructor, prototype, prototype chain collation

1. The difference between ordinary functions and constructors:

(1) Names: Constructors are recommended to start with a capital letter, and ordinary functions are recommended to start with a lowercase letter

(1) Constructor this refers to the new object constructed. The normal function this refers to the window global object; (2) By default, the constructor does not return a value. Ordinary functions usually return a value

If a return is used, the return value varies depending on the type of return value

function Person() {
  var a;
  this.name = 'Jerry'
  this.age = 18
  return a
}
let p1 = new Person()
console.log(p1)  // {name: 'Jerry', age: 18}
let p2 = Person()
console.log(p2) // undefined

If the value of return is a primitive data type, the constructor will ignore the value of return and still return this, whereas normal functions will return the value after return
Copy the code

When a return is a reference type, both the constructor and the normal function return the value after the return

function Person() {
  var a = []
  this.name = 'Jerry'
  this.age = 18
  return a
}
let p1 = new Person()
console.log(p1)  / / []
let p2 = Person()
console.log(p2)  / / []
Copy the code

When a constructor is called with new (var p1 = new Person()), the following happens inside the function:

  1. Create an empty object var obj = {}

  2. This variable refers to object p1 Person.call(p)

  3. P inherits the prototype of Person(), p.__proto__ = person.prototype

  4. Execute the code inside the constructor Person()

  5. The return object P1

2. Constructor

Constructors differ from other functions in that they instantiate objects new, and each constructor has a prototype object (Person in the code below) and a prototype attribute, prototype

function Person(name, age) {
  this.name = name
  this.age = age
  this.sayName = function () {
    console.log(this.name)
  }
}
let p1 = new Person('Jerry'.18)
let p2 = new Person('Tom'.19)
// p1 and p2 are instances of the constructor Person (instantiated object), that is, the constructor attribute of the instance prototype points to the constructor

// Both instances have a constructor property, that is, the instance prototype's constructor property points to the constructor, which points to Person

The Person constructor is the prototype for instantiating object P1
Copy the code

Any function that is new is a constructor, and any function that is new is an instance, and any function can be a constructor

Functions have a prototype property. When a function is declared, it has a prototype property that initializes an empty object, the prototype object

The prototype object has a constructor, which by default points to the declared function.

! [image-20210416010507213](/Users/alex/Library/Application Support/typora-user-images/image-20210416010507213.png)

p1.constructor === Person // true
Copy the code

Constructor features:

  1. The function body uses the this keyword inside, representing the instance of the object to be generated

  2. When generating objects, you must use new

3. What does the constructor new do

function Person(name, age) {
  this.name = name
  this.age = age
}
Person.prototype.say = function () {}
var p1 = new Person('Jerry'.18)
console.log(p1) {name: 'Jerry'.age: 18}
var obj = {}  // Create a new object
Person.call(obj, 'Jack'.19) // Assign the constructor's prototype object to the object's prototype chain
obj.__proto__ = Person.prototype // Change the constructor's this pointer to point to a new object
console.log(obj)  // Return an object
Copy the code

New command principle

  1. Create a new object (as an instance of the object to be returned)

  2. Point the empty object’s prototype to the constructor’s prototype

  3. Assign the empty object to the this keyword inside the function

  4. Start executing the code inside the constructor

  5. If the constructor has a return statement inside it and returns an object, it returns the object specified by the return statement; otherwise, it returns this

If the return statement returns a new object unrelated to this, the new command returns the new object, not this. If you use the new command on ordinary functions (functions that do not have the this keyword inside them), an empty object is returned

4. prototype

In JS, every function has a prototype property that points to the function’s prototype object.

The prototype object prototype has a default constructor property that records which constructor the instance was created by

function Person(name) {
  this.name = name
}
Person.prototype.age = 18
let p1 = new Person()
console.log(p1.age)  / / 18
Copy the code

In the above code, the function’s prototype points to an object that is the prototype of the instance created when the constructor is called, i.e. the prototype of p1, i.e. person.prototype == p1.__proto__

When each JS object is created, it is associated with another object, which is called a prototype, from which each object inherits properties

5.proto

Every object has a __proto__, which points to the prototype of that object. Only function objects have the Prototype attribute

__proto__ is an object with two attributes: constructor and __proto__

function Person() {}
let p1 = new Person()
console.log(Person.prototype === p1.__proto__) // true
console.log(Object.getPrototypeOf(p1) === Person.prototype) // true object.getProtoTypeof () gets the prototype of the Object
Copy the code

6. constructor

Each stereotype has a constructor property that points to the associated constructor

function Person() {}
console.log(Person.prototype.constructor === Person)  // true
let p1 = new Person()
console.log(p1.constructor === Person) // true
/ / p1. Constructor: P1 has no constructor property, so no constructor property can be read. From p1 prototype is Person. Read in the prototype, p1) constructor. = = = Person prototype. The constructor
Copy the code

7. Examples, prototypes

If an instance attribute cannot be found, it will be read from the prototype associated with the object. If it cannot be found, it will be read from the prototype until it reaches the top layer

function Person() {}
Person.prototype.name = 'Jerry'
let p1 = new Person()
p1.name = 'xiaowang'
console.log(p1.name) // xiaowang
delete p1.name
console.log(p1.name) // Jerry
Copy the code

If name is not found in p1, it will be read from p1’s prototype (p1.__proto__), i.e. person.prototype. Here I find name = ‘Jerry’ in the prototype, what if I don’t find it?

8. The prototype of the prototype

A prototype is also an object; that is, an object can be created in the most primitive way

let obj = new Object()
obj.name = 'Jerry'
console.log(obj.name) // Jerry
Copy the code

In fact, the prototype Object is generated through the Object constructor. The __proto__ of the instance points to the prototype constructor.

9. The prototype chain

The core of the prototype chain is the __proto__ reference to an Object. When it doesn’t exist, it goes up until it finds the constructor that created the Object. When it reaches Object, there is no __proto__ reference

Object. Prototype has no __proto__ property. Object. Prototype’s __proto__ points to null. Prototype (array. prototype, etc.) and custom constructors (__proto__) point to Object.prototype. Because prototype objects themselves are ordinary objects

Object.prototype.__proto__ === null // true
Array.prototype.__proto__ === Object.prototype // true
Person.prototype.__proto__ === Object.prototype // true
Copy the code