introduce
Everyone is familiar with constructors, but if you are a novice, it is still necessary to understand what constructors are. The constructor is used to create a specific type of object - not only declares the object used, but also accepts parameters to set the object's member value when the object is created for the first time. You can customize your own constructor and declare the properties or methods of the custom type object.
Basic usage
In JavaScript, constructors are usually considered to be used to implement instances. JavaScript does not have the concept of classes, but has special constructors. Use the new keyword to call the defined early function. You can tell JavaScript that you want to create a new object and that the member declarations of the new object are defined in the constructor. Inside the constructor, this keyword refers to the newly created object. The basic usage is as follows:
The code copy is as follows:
function Car(model, year, miles) {
this.model = model;
this.year = year;
this.miles = miles;
this.output= function () {
return this.model + "left" + this.miles + "km";
};
}
var tom= new Car("Uncle", 2009, 20000);
var dudu= new Car("Dudu", 2010, 5000);
console.log(tom.output());
console.log(dudu.output());
The above example is a very simple constructor pattern, but it's a little bit of a problem. First of all, it is very troublesome to use inheritance. Secondly, output() is redefined every time an object is created. The best way is to let all instances of Car type share this output() method, so that if there are large batches of instances, it will save a lot of memory.
To solve this problem, we can use the following method:
The code copy is as follows:
function Car(model, year, miles) {
this.model = model;
this.year = year;
this.miles = miles;
this.output= formatCar;
}
function formatCar() {
return this.model + "left" + this.miles + "km";
}
Although this method is available, we have the following better method.
Constructors and prototypes
There is a prototype property in JavaScript called prototype. When the constructor is called to create an object, all the properties of the constructor prototype are available on the newly created object. In this way, multiple Car object instances can share the same prototype. Let's expand the code in the above example:
The code copy is as follows:
function Car(model, year, miles) {
this.model = model;
this.year = year;
this.miles = miles;
}
/*
Note: Here we used the Object.prototype. method name, not the Object.prototype
It is mainly used to avoid rewriting the prototype prototype object
*/
Car.prototype.output= function () {
return this.model + "left" + this.miles + "km";
};
var tom = new Car("Uncle", 2009, 20000);
var dudu = new Car("Dudu", 2010, 5000);
console.log(tom.output());
console.log(dudu.output());
Here, output() single instance can be shared and used in all Car object instances.
Also: We recommend that constructors start with capital letters to distinguish ordinary functions.
Can you only use new?
In the example above, the function car is created using new to create objects. Is there only one way? In fact, there are other ways, let’s list two:
The code copy is as follows:
function Car(model, year, miles) {
this.model = model;
this.year = year;
this.miles = miles;
// Customize an output output
this.output = function () {
return this.model + "left" + this.miles + "km";
}
}
//Method 1: Called as a function
Car("Uncle", 2009, 20000); //Add to window object
console.log(window.output());
//Method 2: Call within the scope of another object
var o = new Object();
Car.call(o, "Dudu", 2010, 5000);
console.log(o.output());
Method 1 of this code is a bit special. If new calls the function directly, this points to the global object window. Let's verify it:
The code copy is as follows:
//As a function call
var tom = Car("Uncle", 2009, 20000);
console.log(typeof tom); // "undefined"
console.log(window.output()); // "Uncle walked 20,000 kilometers"
At this time, the object tom is undefined, and window.output() will output the result correctly. If you use the new keyword, there is no such problem. The verification is as follows:
The code copy is as follows:
//Use new keyword
var tom = new Car("Uncle", 2009, 20000);
console.log(typeof tom); // "object"
console.log(tom.output()); // "Uncle walked 20,000 kilometers"
Force new
The above example shows the problem of not using new. So is there a way for the constructor to force the new keyword? The answer is yes, above code:
The code copy is as follows:
function Car(model, year, miles) {
if (!(this instanceof Car)) {
return new Car(model, year, miles);
}
this.model = model;
this.year = year;
this.miles = miles;
this.output = function () {
return this.model + "left" + this.miles + "km";
}
}
var tom = new Car("Uncle", 2009, 20000);
var dudu = Car("Dudu", 2010, 5000);
console.log(typeof tom); // "object"
console.log(tom.output()); // "Uncle walked 20,000 kilometers"
console.log(typeof dudu); // "object"
console.log(dudu.output()); // "Dudu walked 5000 kilometers"
By judging whether this instanceof is Car, we decide to return new Car or continue to execute the code. If the new keyword is used, (this instanceof Car) is true, and the following parameter assignment will continue. If new is not used, (this instanceof Car) is false, and a new instance will be returned again.
Original wrapper function
There are 3 original wrapper functions in JavaScript: number, string, boolean, sometimes both are used:
The code copy is as follows:
// Use original wrapper function
var s = new String("my string");
var n = new Number(101);
var b = new Boolean(true);
// Recommend this
var s = "my string";
var n = 101;
var b = true;
Recommended, only use these wrapper functions when you want to preserve the numerical state. For the difference, you can refer to the following code:
The code copy is as follows:
// Original string
var greet = "Hello there";
// Use split() method to split
greet.split(' ')[0]; // "Hello"
// Adding new attributes to the original type will not report an error
greet.smile = true;
// This value cannot be obtained (We talked about why in Chapter 18 ECMAScript implementation)
console.log(typeof greet.smile); // "undefined"
// Original string
var greet = new String("Hello there");
// Use split() method to split
greet.split(' ')[0]; // "Hello"
// Adding new attributes to the wrapper function type will not report an error
greet.smile = true;
// New properties can be accessed normally
console.log(typeof greet.smile); // "boolean"
Summarize
This chapter mainly explains the differences between the use of constructor mode, calling method and new keyword. I hope everyone will pay attention to it when using it.
Reference: http://www.addyosmani.com/resources/essentialjsdesignpatterns/book/#constructorpatternjavascript