This is the fourth day of my participation in Gwen Challenge

The original intention of this series of articles is to “let each front-end engineer master the high frequency knowledge, for the work of power”. This is the front of the first hundred cut the 18th cut, I hope friends pay attention to the public number “kite”, armed with knowledge of their minds.

18.1 basis

New creates an instance object from the constructor. The relationship between the instance and the prototype and constructor is shown below:

18.2 What happens in the New process

What exactly happens when a constructor new happens? The brief overview is mainly divided into the following steps:

  1. A new object is created;
  2. The object’s __ proto __ property points to the constructor’s prototype, that is, Fn. Prototype;
  3. Bind the execution context (this) to the newly created object;
  4. If the constructor has a return value (object or function), that return value replaces the newly created object in the first step.

Did New really do these steps? In keeping with the principle that “practice is the sole criterion for testing truth,” here are a few key points to examine one by one.

function Fun() {
    this.a = 10;
    this.b = 20;
    this.method1 = () = > {
        return this.a + this.b;
    }
    this.method2 = () = > {
        return this;
    }
}

Fun.prototype = {
    method2: () = > {
        console.log('Method1 is called on the prototype'); }}Copy the code

18.2.1 Verification Point 1 — A new object is created

Verification point 1 is the creation of a new object, which has two implications:

  1. The content returned after new is an object
const fun = new Fun();
console.log(fun); // { a: 10, b: 20, method1: [Function] }
console.log(typeof(fun)); // object
Copy the code

By printing its contents and verifying with typeof, the returned contents are indeed an object.

  1. Each time it returns a newly created object
const fun1 = new Fun();
const fun2 = new Fun();
console.log(fun1 === fun2); // false
Copy the code

By creating two instances, and by determining that the two instances are not equal, we prove that we are indeed returning a new object each time.

18.2.2 Verification point 2 — This object has access to properties and methods on the stereotype

Verification point 2 means that the newly created instance can access the properties and methods on the prototype. Verification of this key point can be realized only by accessing the methods on the prototype. If the methods on the prototype can be accessed normally, it means that the verification point passes, and the verification point does not pass.

const fun3 = new Fun();
fun3.method3(); Method3 is called on the prototype
Copy the code

By verification, the method on the prototype can actually be accessed.

18.2.3 Verification point 3 — This points to

To verify this point, just print this point out.

const fun4 = new Fun();
console.log(fun4.method2()); // { a: 10, b: 20, method1: [Function], method2: [Function] }
console.log(fun4.method2() === fun4); // true
Copy the code

18.2.4 Verification point 4 — The constructor has processing logic that returns a value

A function can return multiple values, such as string, Boolean, number, Object, function, etc.

  1. The return value is string
function Fun() {
    this.a = 10;
    this.b = 20;
    return 'test';
}
Fun.prototype = {
    method: () = > {
        console.log('Method on prototype is accessed'); }}const fun = new Fun();
console.log(fun); // { a: 10, b: 20 }
Copy the code

The final result is that the string does not return properly, and the return value is a new instance.

  1. The return value is Object
function Fun() {
    this.a = 10;
    this.b = 20;
    return {
        c: 30
    };
}
Fun.prototype = {
    method: () = > {
        console.log('Method on prototype is accessed'); }}const fun = new Fun();
console.log(fun); // { c: 30 }
Copy the code

When a constructor returns an object, it returns its object, but not its instantiated content.

  1. Return function
function Fun() {
    this.a = 10;
    this.b = 20;
    return function() {
        this.d = 40;
    };
}
Fun.prototype = {
    method: () = > {
        console.log('Method on prototype is accessed'); }}const fun = new Fun();
console.log(fun); // [Function]
Copy the code

The effect of returning a function is the same as that of returning an object.

The following conclusions can be drawn through repeated attempts:

  1. The return value of the constructor is a primitive type, and its return value is the instantiated object, unaffected by the return value.
  2. The return value of the constructor is a reference type, which is the value returned after new.

18.3 Implement a new

With that said, now that you understand what happens when new and have verified it, let’s manually implement a new function of your own.

function myNew(Fn, ... args) {
    // A new object is created
    const result = {};
    // The object's __proto__ attribute points to the prototype of the constructor
    if(Fn.prototype ! = =null) {
        Object.setPrototypeOf(result, Fn.prototype);
    }

    // Bind the execution context (this) to the newly created object
    const returnResult = Fn.apply(result, args);
    If the constructor has a return value (object or function), the return value replaces the newly created object in the first step.
    if ((typeof returnResult === 'object' || typeof returnResult === 'function') && returnResult ! = =null) {
        return returnResult;
    }
    return result;
}
Copy the code

A profound

function Fun() {
    this.a = 10;
    this.b = 20;
}
Fun.prototype = {
    method: () = > {
        console.log('Method on prototype is accessed'); }}const fun1 = new Fun();
console.log(fun1); // { a: 10, b: 20 }
const fun2 = myNew(Fun);
console.log(fun2); // { a: 10, b: 20 }
Copy the code

1. If you think this article is good, share and like it so that more people can see it

2. Pay attention to the public number of kite, and the number of the Lord together to kill the front hundred