preface

What can you learn from this article?

  • Constructors, or constructors for short, are normal functions, but there is a common convention for constructors to be named with a capital letter.

  • Constructors can only be called using new. Such a call means that an empty this is created at the beginning and a value-populated this is returned at the end.


The conventional {… } syntax allows you to create an object. But we often need to create many similar objects, such as multiple users or menu items.

This can be done using the constructor and the “new” operator.

The constructor

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

  1. Their names begin with a capital letter.
  2. They can only be made"new"Operator to execute.

Such as:

function User(name) {
  this.name = name;
  this.isAdmin = false;
}

let user = new User("Jack");

alert(user.name); // Jack
alert(user.isAdmin); // falseCopy the code

When a function is executed using the new operator, it follows these steps:

  1. A new empty object is created and assigned tothis.
  2. The function body executes. Usually it will modifythisAdd a new attribute to it.
  3. returnthisThe value of the.

In other words, new User(…) It does something like this:

function User(name) {
  // this = {}; (Implicitly created)

  // Add attributes to this
  this.name = name;
  this.isAdmin = false;

  // return this; (Implicit return)
}Copy the code

So new User(“Jack”) results in the same object:

let user = {
  name: "Jack".isAdmin: false
};Copy the code

Now, if we want to create other users, we can call new User(“Ann”), new User(“Alice”), etc. It’s much shorter and easier to read than using a literal creation every time.

This is the main purpose of constructors – to achieve reusable object creation code.

Let’s say it again — technically, any function can be used as a constructor. That is, any function can be run through new, which executes the algorithm above. “Capitalize” is a common convention to make it clear that a function will be run using new.

The new function () {… }

If we have many lines of code to create a single complex object, we can wrap them in a constructor like this:

let user = new function() {
  this.name = "John";
  this.isAdmin = false;

  / /... Additional code for user creation
  // Perhaps complex logic and statements
  // Local variables, etc
};Copy the code

The constructor cannot be called again because it is not stored anywhere, just created and called. Thus, this technique aims to encapsulate the code that builds a single object without future reuse.

Double syntax constructor: new.target

Advanced content

The syntax covered in this section is rarely used, so you can skip it unless you want to know everything.

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:

This approach is sometimes used in libraries to make syntax more flexible. So when people call a function, whether new is used or not, the program will work.

However, using it everywhere is not a good thing, because the omission of new makes it hard to see what is happening in the code. And by new we all know that this creates a new object.

Constructor Return

Normally, constructors do not have return statements. Their job is to write everything necessary to this and automatically convert it to the result.

However, if there is a return statement, the rule is simple:

  • ifreturnIf an object is returned, the object is returned instead ofthis.
  • ifreturnReturns a primitive type, then ignores it.

In other words, a return with an object returns that object, and in all other cases returns this.

For example, here return overrides this by returning an object:

Here is an example where return is empty (or we can put a primitive type after it, which has no effect) :

Usually constructors do not have return statements. Here we refer primarily to the special behavior of returning objects for completeness.

Omit the parentheses

By the way, if there are no arguments, we can omit the parentheses after new:

let user = new User; // <-- no arguments
/ / is equivalent to
let user = new User();Copy the code

The omission of parentheses here is not considered a “good style,” but the specification allows it.

A method in a constructor

Using constructors to create objects provides great flexibility. A constructor may have parameters that define how the object is constructed and what to put in it.

Of course, we can add methods as well as properties to this.

For example, the following new User(name) creates an object with the given name and method sayHi:

function User(name) {
  this.name = name;

  this.sayHi = function() {
    alert( "My name is: " + this.name );
  };
}

let john = new User("John");

john.sayHi(); // My name is: John

/* john = { name: "John", sayHi: function() { ... }} * /Copy the code

Classes are a more advanced syntax for creating complex objects, which we’ll cover later.

conclusion

  • Constructors, or constructors for short, are normal functions, but there is a common convention for constructors to be named with a capital letter.
  • Constructors can only be usednewTo invoke. Such a call means that an empty is created at the beginningthisAnd returns the filled value at the endthis.

We can use constructors to create multiple similar objects.

A few small tasks

Degree of importance: **

Is it possible to create functions A and B like new A()==new B()?

function A() {... }function B() {... }let a = new A;
let b = new B;

alert( a == b ); // trueCopy the code

If you can, provide a code example of them.

The solution

Yes, that’s ok.

If a function returns an object, then new returns that object instead of this.

So they can, for example, return the same externally defined object obj:

let obj = {};

function A() { return obj; }
function B() { return obj; }

alert( new A() == new B() ); // trueCopy the code

Create a new Calculator

Degree of importance: *****

Degree of importance: *****

Create an Accumulator constructor (startingValue).

The object it creates should:

  • Stores the current value in the propertyvalueIn the. The start value is set to the constructor’sstartingValueParameters.
  • read()Method should usepromptTo read a new number and add it tovalueIn the.

In other words, the value property is the sum of all user input values plus the initial startingValue.

Here is the sample code:

let accumulator = new Accumulator(1); // Initial value 1

accumulator.read(); // Add the value entered by the user
accumulator.read(); // Add the value entered by the user

alert(accumulator.value); // Display the sum of these valuesCopy the code

The solution
function Accumulator(startingValue) {
  this.value = startingValue;

  this.read = function() {
    this.value += +prompt('How much to add? '.0);
  };

}

let accumulator = new Accumulator(1);
accumulator.read();
accumulator.read();
alert(accumulator.value);Copy the code