Deep understanding of JavaScript series (26): Constructor pattern of design patterns

This article is reproduced from: http://www.cnblogs.com/tomxu/archive/2012/02/21/2352994.html Author: TomXu Please indicate the statement when reprinting.

introduce

Constructors are familiar to everyone, but if you are a novice, it is necessary to understand what a constructor is. Constructors are used to create objects of a specific type - not only do they declare the objects to be used, but they can also accept parameters to set the member values ​​of the object when it is first created. You can customize your own constructor, and then declare properties or methods of custom type objects in it.

Basic usage

In JavaScript, constructors are usually considered to be used to implement instances. JavaScript has no concept of classes, but has special constructors. By calling a defined function with the new keyword, 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, the this keyword refers to the newly created object. The basic usage is as follows:

function Car(model, year, miles) {
   this.model = model;this.year = year;this.miles = miles;this.output= function () {
   returnthis.model + "走了" + this.miles + "公里";    };}var tom= new Car("大叔", 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 has a little problem. First of all, it is very troublesome to use inheritance, and 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 a large number of instances If so, it will save a lot of memory.

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

function Car(model, year, miles) {
   this.model = model;this.year = year;this.miles = miles;this.output= formatCar;}function formatCar() {
   returnthis.model + "走了" + this.miles + "公里";}
   








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

Constructor and Prototype

Functions in JavaScript have a prototype property called prototype. When calling a constructor 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 of the above example:

function Car(model, year, miles) {
    this .model = model; this .year = year; this .miles = miles; } /* Note: Here we use Object.prototype. method name, not Object.prototype main It is used to avoid overriding the definition prototype prototype object */ Car.prototype.output= function () {
    return this .model + "go" + 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, the single instance of output() can be shared among all Car object instances.

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

Can only use new?

The above example uses new to create objects for the function car. Is there only one way? In fact, there are other ways, we list two:

function Car(model, year, miles) {
    this .model = model; this .year = year; this .miles = miles; // Customize an output output this .output = function () {
    return this .model + " Go" + this .miles + "km";     } } // Method 1: Call Car("Uncle", 2009, 20000) as a function;   // Add to the window object console.log(window.output()) ; // Method 2: call in 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 directly call the function, this points to the global object window. Let's verify it:

// as a function call var tom = Car("Uncle", 2009, 20000); console.log( typeof tom); // "undefined" console.log(window.output()); // "Uncle left 20000 kilometer"


At this time, the object tom is undefined, and window.output() will output the result correctly, but if the new keyword is used, there is no such problem. The verification is as follows:

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


Force the use of new

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

function Car(model, year, miles) {
   if (!(thisinstanceof Car)) {
   returnnew Car(model, year, miles);    }this.model = model;this.year = year;this.miles = miles;this.output = function () {
   returnthis.model + "走了" + this.miles + "公里";    }}var tom = new Car("大叔", 2009, 20000);var dudu = Car("Dudu", 2010, 5000);console.log(typeof tom); // "object"
   















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

By judging whether the instanceof of this is Car, it is decided whether to return to new Car or continue to execute the code. If the new keyword is used, (this instanceof Car) is true, and the following parameter assignments will continue to be executed. If new is not used, (this instanceof Car) is false, and a new instance will be returned.

original wrapper function

There are 3 primitive wrapper functions in JavaScript: number, string, boolean , and sometimes both are used:

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








It is recommended to use these wrapper functions only when you want to preserve the numerical state. For the difference, you can refer to the following code:

// original string var greet = "Hello there"; // Use split() method to split greet.split(' ')[0]; // "Hello" // Adding new properties to primitive types will not throw an error 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 "); // Use the split() method to split greet.split(' ')[0]; // "Hello" // Adding a new attribute to the wrapper function type will not report an error greet.smile = true ;// The new property can be accessed normally















console.log(typeof greet.smile); // "boolean"

Summarize

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

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

Sync and recommend

This article has been synchronized to the directory index: Deep understanding of JavaScript series

In-depth understanding of the JavaScript series of articles, including original, translated, reprinted and other types of articles, if it is useful to you, please recommend to support it and give the uncle the motivation to write.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=324119498&siteId=291194637