The new keyword in js is mainly used when creating objects as constructors, like this:

 function Foo(name, age, sex) {
     this.name = name
     this.age = age
     this.sex = sex
     // return 1 // If a primitive data type is returned, the person below generates an object
     Return {a:1} // If a non-basic data type is returned, the person below is {a:1}.
 }
 var person = new Foo('Ming'.'18'.'male')
 consloe.log(person)
 console.log(person.name)  / / xiao Ming
Copy the code

We find that the constructor does not show any return value. What if it does?

 function Foo(name, age, sex) {
     this.name = name
     this.age = age
     this.sex = sex
     return 1  
 }
 var person = new Foo('Ming'.'18'.'male')
 consloe.log(person)
 console.log(person.name)  / / xiao Ming
Copy the code

Returns a 1, but it doesn’t make any difference, and the result doesn’t change. This leads to the conclusion that if the constructor returns a primitive value type, it actually generates an empty object, which doesn’t make any sense

What if you return an object?

 function Foo(name, age, sex) {
     this.name = name
     this.age = age
     this.sex = sex
     return {a:1} // If a non-basic data type is returned, the person below is {a:1}.
 }
 var person = new Foo('Ming'.'18'.'male')
 consloe.log(person)  //{a:1}
 console.log(person.name)  //undefined
Copy the code

If an object is returned, the value of the object is returned normally

Return result Note:

When you get an object this way, you don’t necessarily end up returning an object, depending on what the constructor returns. If the constructor returns a primitive value type, it actually generates an object. If the constructor returns a reference value type, it actually returns that reference value type.

The previous code makes it easy to think that Foo is a constructor because we call it with new and see that it “constructs” an object. In fact, Foo is no different from any other function in your program. The function itself is not a constructor; however, when you prefix a normal function call with the new keyword, you make the function call a “constructor call.” In effect, new hijacks all ordinary functions and calls them as constructors. In other words, the most accurate definition of “constructor” in JavaScript is all function calls with new. A function is not a constructor, but a function call becomes a “constructor call” if and only if new is used. So how exactly does the new keyword construct an object that has the properties and methods of a “constructor”? How does it work internally?

newKey words to create instance object steps:

  • 1. Create a new object, such as var person={}, because the new keyword returns an object
  • 2. The __proto__ attribute of the new object points to the protoobject of the constructor
  • 3. Assign the scope of the constructor to the new object (that is, this refers to the new object)
  • 4. Return the new object Person

We can manually wrap a new keyword

// fn is the constructor
function myNew(fn, ... args) {
    const obj = {};
    obj.__proto__ = fn.prototype;
    // Change this pointer
    let result = fn.apply(obj, args)
    // return result
    // Make sure new comes out as an object
    return typeof result === "object" ? result : obj
}
Copy the code

Let’s test that out

 function Student(name, age, sex) {
    this.name = name;
    this.age = age;
    this.sex = sex;
    this.play=function(){
        console.log('hhhhhhh')}}var student1 = myNew(Student, 'Ming'.18.'male')
console.log(student1) //{name: "xiao Ming ", age: 18, sex:" male ", play: ƒ}
Copy the code

Reference: JavaScript You Don’t Know (Volume 1)