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:
- Their names begin with a capital letter.
- 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:
- A new empty object is created and assigned to
this
. - The function body executes. Usually it will modify
this
Add a new attribute to it. - return
this
The 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.
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
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:
- if
return
If an object is returned, the object is returned instead ofthis
. - if
return
Returns 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.
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 used
new
To invoke. Such a call means that an empty is created at the beginningthis
And returns the filled value at the endthis
.
We can use constructors to create multiple similar objects.
A few small tasks
Two functions – one object
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.
Degree of importance: *****
Create a constructor Calculator that creates an object with three methods:
read()
useprompt
Request two values and record them in the properties of the object.sum()
Returns the sum of these attributes.mul()
Returns the product of these attributes.
Such as:
let calculator = new Calculator();
calculator.read();
alert( "Sum=" + calculator.sum() );
alert( "Mul=" + calculator.mul() );Copy the code
function Calculator() {
this.read = function() {
this.a = +prompt('a? '.0);
this.b = +prompt('b? '.0);
};
this.sum = function() {
return this.a + this.b;
};
this.mul = function() {
return this.a * this.b;
};
}
let calculator = new Calculator();
calculator.read();
alert( "Sum=" + calculator.sum() );
alert( "Mul=" + calculator.mul() );Copy the code
Create new Accumulator
Degree of importance: *****
Create an Accumulator constructor (startingValue).
The object it creates should:
- Stores the current value in the property
value
In the. The start value is set to the constructor’sstartingValue
Parameters. read()
Method should useprompt
To read a new number and add it tovalue
In 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