Home >Web Front-end >JS Tutorial >In-depth understanding of JavaScript series (26): Detailed explanation of the constructor pattern of design patterns_javascript skills

In-depth understanding of JavaScript series (26): Detailed explanation of the constructor pattern of design patterns_javascript skills

WBOY
WBOYOriginal
2016-05-16 16:11:28812browse

Introduction

Everyone is familiar with constructors, but if you are a novice, it is still necessary to understand what a constructor is. A constructor is used to create an object of a specific type - not only does it declare the object to be used, the constructor can also accept parameters to set the object's member values ​​when the object is first created. You can customize your own constructor and declare properties or methods of custom type objects in it.

Basic usage

In JavaScript, constructors are usually used to implement instances. JavaScript does not have the concept of classes, but there are special constructors. By calling the defined function using the new keyword, you can tell JavaScript that you want to create a new object and the member declarations of the new object are all defined in the constructor. Inside the constructor, the this keyword refers to the newly created object. The basic usage is as follows:

Copy code The code is as follows:

function Car(model, year, miles) {
This.model = model;
This.year = year;
This.miles = miles;
This.output= function () {
          return this.model "Gone" this.miles "Kilometers";
};
}

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 there are a few problems. First of all, using inheritance is very troublesome. Secondly, output() is redefined every time an object is created. The best way is to let all instances of the Car type share this output() method, so that if there are a large number of instances If so, it will save a lot of memory.

To solve this problem, we can use the following methods:

Copy code The code 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 "Gone" this.miles "Kilometers";
}


Although this method is available, we have a better method as follows.

Constructor and prototype

The function in JavaScript has a prototype attribute called prototype. When a constructor is called to create an object, all the attributes of the constructor prototype are available on the newly created object. According to this, multiple Car object instances can share the same prototype. Let’s expand the code of the above example:

Copy code The code is as follows:

function Car(model, year, miles) {
This.model = model;
This.year = year;
This.miles = miles;
}

/*
Note: Here we use Object.prototype. method name instead of Object.prototype
Mainly used to avoid rewriting the defined prototype prototype object
*/
Car.prototype.output= function () {
Return this.model "Gone" this.miles "Kilometers";
};

var tom = new Car("Uncle", 2009, 20000);
var dudu = new Car("Dudu", 2010, 5000);

console.log(tom.output());
console.log(dudu.output());


Here, the output() single instance can be shared among all Car object instances.

Also: We recommend that constructors start with a capital letter to distinguish them from ordinary functions.

Can I only use new?

The above examples all use new to create objects for the function car. Is this the only way? In fact, there are other ways, we list two:

Copy code The code is as follows:

function Car(model, year, miles) {
This.model = model;
This.year = year;
This.miles = miles;
// Customize an output content
This.output = function () {
          return this.model "Gone" this.miles "Kilometers";
}
}

//Method 1: Call 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 you don’t use new to call the function directly, this points to the global object window. Let’s verify it:
Copy code The code is as follows:

//Call as a function
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. However, if you use the new keyword, there will be no such problem. The verification is as follows:
Copy code The code is as follows:

//Use new keyword
var tom = new Car("Uncle", 2009, 20000);
console.log(typeof tom); // "object"
console.log(tom.output()); // "Uncle has walked 20,000 kilometers"

Force new

The above example shows the problem of not using new, so is there any way for us to force the constructor to use the new keyword? The answer is yes, the above code:

Copy code The code 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 "Gone" this.miles "Kilometers";
}
}

var tom = new Car("Uncle", 2009, 20000);
var dudu = Car("Dudu", 2010, 5000);

console.log(typeof tom); // "object"
console.log(tom.output()); // "Uncle has walked 20,000 kilometers"
console.log(typeof dudu); // "object"
console.log(dudu.output()); // "Dudu walked 5000 kilometers"


By judging whether the instanceof of this is Car, you can decide whether 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.

Original wrapper function

There are three primitive wrapper functions in JavaScript: number, string, boolean. Sometimes both are used:

Copy code The code is as follows:

// Use original wrapper function
var s = new String("my string");
var n = new Number(101);
var b = new Boolean(true);


// This is recommended
var s = "my string";
var n = 101;
var b = true;


It is recommended to use these wrapper functions only when you want to retain the numerical state. For the difference, please refer to the following code:
Copy code The code is as follows:

// original string
var greet = "Hello there";
// Split
using split() method greet.split(' ')[0]; // "Hello"
// No error will be reported when adding new attributes to primitive types
greet.smile = true;
// There is no way to get this value (we talked about why in Chapter 18 ECMAScript Implementation)
console.log(typeof greet.smile); // "undefined"

//original string
var greet = new String("Hello there");
// Split
using split() method greet.split(' ')[0]; // "Hello"
// Adding new attributes to the wrapper function type will not cause an error
greet.smile = true;
// New properties can be accessed normally
console.log(typeof greet.smile); // "boolean"

Summary

This chapter mainly explains how to use the constructor pattern, how to call it, and the difference between the new keyword. I hope everyone will pay attention to it when using it.

Reference: http://www.addyosmani.com/resources/essentialjsdesignpatterns/book/#constructorpatternjavascript

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn