Before you do, ask yourself a few questions:

  • What is a constructor? What’s the difference between a normal function?

  • Can all functions be new?

  • What does the new operator do?

  • How do I implement a new myself?

  • New.target?

If not too clear, muddled words, do not panic, might as well read ~

This article focuses on solving these problems.

I believe that after reading carefully, you will be on the above problems have harvest ~

The constructor

For developers who have worked with class-based languages such as Java or C++, JavaScript is a bit confusing because it is dynamic and does not provide a class implementation of its own. (The class keyword was introduced in ES2015/ES6, but that’s just syntactic sugar and JavaScript is still prototype-based). Even the “class” we mock up is just a function object. Classes and functions are indistinguishable in Javascript, and it seems that we can only make specifications, such as the constructor pattern, that are not strictly prescriptive: a custom function whose first letter is capitalized is a constructor. Technically, any function (except the arrow function) can be used as a constructor. That is, any function outside the arrow function can be run through new.

The main purpose of the constructor is to implement reusable object creation code.

Constructors are technically regular functions. But there are two agreements:

  1. Their names begin with a capital letter.

  2. They can only be executed by the “new” operator.

    Such a call means that an empty this is created at the beginning and a value-populated this is returned at the end.

new

The new operator creates an instance of a user-defined object type or of a built-in object with a constructor.

A simple example of new:

function Person(){
   this.name = 'Jack';
}
var p = new Person(); 

console.log(p) // Person {name: "Jack"}
Copy the code

What if you don’t use the new keyword?

function Person(){
  this.name = 'Jack';
}
var p = Person();

console.log(p) // undefined
console.log(name) // Jack
console.log(p.name) // 'name' of undefined
Copy the code

We find that if the constructor is called without the new keyword, undefined is returned, because this is called in the global environment to point to the window.

So what does it look like when you return an object from a constructor?

function Person(){
   this.name = 'Jack'; 
   return {age: 18}}var p = new Person(); 

console.log(p)  // {age: 18}
console.log(p.name) // undefined
console.log(p.age) / / 18
Copy the code

We found that when the constructor returns an object unrelated to this, the new command returns the new object directly, instead of the this object generated by the new execution step.

Note: The constructor must return an object. If it is not an object, it returns the newly generated object as new did. Example:

function Person(){
   this.name = 'Jack'; 
   return 'tom';
}
var p = new Person(); 

console.log(p)  // {name: 'Jack'}
console.log(p.name) // Jack
Copy the code

So let’s conclude:

newKeyword execution always returns an object, either an instance object or an instance objectreturnThe object specified by the statement.

newWhat did you do?

The new keyword does the following:

  1. Create an empty object (i.e{})
  2. Links the object (sets the object’sconstructor) to another object
  3. Take the object newly created in Step 1 asthisThe context in which the
  4. Returns if the object does not return an objectthis

Frequent interview questions: Handwritingnew

function _new(Ctor,... args){
  // Ctor must be a constructor and cannot be an arrow function
  if(! Ctor.prototype){throw new TypeError(`${Ctor} is not a constructor`)}// Create a new empty object
  let obj = {};
  // Associate the object's prototype with the constructor's prototype
  obj.__proto__ = Object.create(Ctor.prototype)
  // This, which takes the created object as the context, executes the constructor
  let res = Ctor.apply(obj, args)
  let isObj = typeof res === 'object' && typeofres ! = =null
  let isFun = typeof res === 'function'
  // Return the result of this new object, the constructor's return; If it is not an object, the newly generated object is returned.
  return isObj || isFun ? res : obj;
}
Copy the code

new.target

Inside a function, we can use the new.target property to check if it was called with new.

For regular calls, it is null, and for calls using new, it is equal to the function:

function User() {
  alert(new.target);
}

// no "new" :
User(); // undefined

/ / with "new" :
new User(); // function User { ... }
Copy the code

It can be used inside a function to determine whether the function is called in “constructor mode” through new or “normal mode” without being called through new.

We can also make the new call do the same thing as the regular call, like this:

function User(name) {
  if (!new.target) { // If you don't run me through new
    return new User(name); / /... I'm going to add new to you
  }

  this.name = name;
}

let john = User("John"); // Redirect the call to the new user
alert(john.name); // John
Copy the code

The last

If have a problem, please big guy correct ~

If helpful, hope to be able to click on the collection ~

References:

  • The new operator of MDN
  • Modern JavaScript Tutorial
  • Hotpot boy’s handwriting new