Singleton mode


To start, we need to describe two people in the program. These two people have names and ages, which might be written like this when you are just starting to learn JS:

var name1 = 'iceman';
var age1 = 25;

var name2 = 'mengzhe';
var age2 = 26;Copy the code

The above description does describe two people, each with a name and age, but the name and age of each person are not put together, that is, the age and name of each person do not correspond. At this point, we introduce the concept of object: put the attributes and methods describing the same thing (same object) under the same memory space, which plays a role of grouping, so that the attributes of different things will not conflict with each other even if the attribute name is the same.

var person1 = {
    name:'iceman'.age:25
};

var person2 = {
    name:'mengzhe'.age:26
};Copy the code

This can be thought of as grouping code in such a way that everyone’s name and age are in the same block of memory. We also call this pattern of grouping code singletons (also called object literals in JavaScript Advanced Programming), and in singletons person1 and person2 are namespaces.

Note: This is how the singleton pattern is written in JavaScript, and it is very different from the singleton pattern in other languages. Many Java programmers may not think this is the singleton pattern, but it is the language difference.

Singleton pattern is often used in a project development model, because of the projects we can use the singleton pattern to modular development, for a relatively large project, the need to more collaborative development, so generally according to the demand of the current project, divided into several functional modules, each person is responsible for the part of the development at the same time, Finally, merge everyone’s code, for example:

  • Public modules: Provide public methods

    var utils = {
      select:function () {
          / /...}};Copy the code
  • Page TAB module: realize TAB switching

    var tabModule = {
      change:function () {
          utils.select(); // Call methods of other namespaces in your own namespace}};Copy the code
  • Search module: realize the processing of search content changes

    var searchModule  = {
      change:function () {
          this.clickEvent(); // Call the method of calling your own namespace in your own namespace
      },
      clickEvent:function () {
          / /...}};Copy the code

In the example above, there are change methods in the tabModule and searchModule. If you do not write them separately, there will be a naming conflict. According to the parsing rules of the JavaScript language, the method declared later will override the method declared earlier. However, after module division, the change methods in these two modules belong to their own modules, and they call the methods in their own modules (tabmodule.change (), searchModule.change())), without conflict.

Ii. Factory model


Review the singleton pattern:

var person1 = {
    name:'iceman'.age:25.writeJs:function () {
        console.log(this.name + 'write js'); }}; person1.writeJs();Copy the code

The singleton pattern solves the problem of grouping, giving each object its own namespace, but it cannot be mass-produced, and every new object has to be rewritten with a copy of the same code. By this time had a factory pattern, namely: the same code, to achieve the same thing in a function, later if you want to realize this function, don’t need to write the code, as long as the execution of the current function, this is the function of encapsulation, embodies the ideas of high cohesion and low coupling: reduce the redundancy in the code page, improve code reuse rate:

function createPerson(name, age) {
    var obj = {};
    obj.name = name;
    obj.age = age;
    obj.writeJs = function () {
        console.log(this.name + 'write js');
    }
    return obj;
}

var p1 = createPerson('mengzhe' , 26);
p1.writeJs();

var p2 = createPerson('iceman' , 25);
p2.writeJs();Copy the code

Overloading, by the way: In Java, c #, strong type of object oriented programming language, such as the concept of function overloading, but there is no overloading in JavaScript, if the method name, behind the front cover, and finally to keep only the definition of a method, but we can according to the parameters passed, simulating overloaded functions:

function sum(num) {
    if (typeof num === 'undefined') {
        return 0;
    }
    return num;
}
sum(100);
sum();Copy the code

Constructor pattern


function CreateJsPerson(name, age) {
    this.name = name;
    this.age = age;
    this.writeJs = function () {
        console.log(this.name + 'write js');
    }
    // The browser returns the created instance by default
}
var p1 = new CreateJsPerson('iceman' , 25);
p1.writeJs();
var p2 = new CreateJsPerson('mengzhe' , 26);
p2.writeJs();Copy the code

New CreateJsPerson(‘iceman’, 25); new CreateJsPerson(‘iceman’, 25);

var res = CreateJsPerson('xx' , 7);Copy the code

Instead of calling a function directly with new, it is not a constructor but a normal function. Since there is no return, res=undefined, and this in CreateJsPerson is window.

The purpose of the constructor pattern is to create a custom class and create an instance of that class.

The difference between constructor mode and normal function mode:
  • At execution time

    • Normal function execution: CreateJsPerson()
    • The constructor executes: new CreateJsPerson(). When executed with new, CreateJsPerson is a class, and the return value of this function is an instance of the class CreateJsPerson.
  • When the function code executes

    • Same: both form a private scope and then go through: parameter assignment –> preinterpret –> code executes from top to bottom (the class executes just like a normal function, it also has a normal function side).
    • Instead of creating an object manually before the constructor code is executed, the browser creates a value of the object data type by default (the value of the object type is actually an instance of the current class). Next, the code executes from top to bottom, taking the current instance as the subject of execution (this represents the current instance), and assigns the property name and value to the current instance respectively. ③ Finally, the browser returns the created instance by default.
Note:
  • All classes in JavaScript are of function data type, which becomes a class with new execution, but is itself a normal function;
  • All instances in JavaScript are of object data type;
  • In constructor mode, occurs in a class (function body)this.xx = xxIn thethisIs an instance of the current class;
  • P1 and P2 are CreatePerson instances, so they both have writeJs, but the writeJs method is different from one instance to another. Attributes added to an instance in a class (this. XXX = XXX) are private attributes of the current instance. So private attributes are not equal to each other
    console.log(p1.writeJs === p2.writeJs); // --> falseCopy the code

4. Extension of knowledge of constructor patterns


4.1. This occurs in the class

function Fn() {
    this.x = 100;
    this.getX = function () {
        // this-> getX -> getX -> getX -> getX -> getX
        console.log(this.x);
    };
}
var f1 = new Fn;
f1.getX(); // This in the 100 method is f1

var xx = f1.getX;
xx(); // This in undefined is windowCopy the code

Create the object new Fn() in constructor mode. If Fn does not need to pass arguments, the following parentheses can be omitted: new Fn

XXX = XXX; this = XXX; this = XXX; this = XXX; this = XXX

4.2. Private Variables

function Fn() {
    var num = 10;
    this.x = 100; // f1.x = 100
    this.getX = function () { // f1.getX=function
        console.log(this.x);
    };
}
var f1 = new Fn;
console.log(f1.num); // -> undefinedCopy the code

When the function is executed, var num is a private variable in the current private scope. It has nothing to do with f1 instance. Only this. XXX = XXX can add private attributes and methods to F1 instance.

4.3. Return in class

function Fn() {
    this.x = 100;
    this.getX = function () {
        console.log(this.x);
    };
// return 100;
    return {name:'iceman'};
}
var f1 = new Fn;
console.log(f1);Copy the code

In constructor mode, the browser will return our instance by default (it will return the value of an object datatype) if we manually write a return:

  • Returns a value of a base datatype: the current instance value is constant, for example:return 100, f1 is still an instance of the current Fn class;
  • Returns a value that refers to a datatype: the current instance will be replaced by its own returned instance, for example:return {name:'icmean'}In this case, f1 is not an instance of Fn, but the object returned;

4.4. Check whether the instance belongs to a class

function Fn() {
    this.x = 100;
    this.getX = function () {
        console.log(this.x);
    };
}
var f1 = new Fn;
console.log(f1 instanceof Fn); // --> true
console.log(f1 instanceof Array); // --> false
console.log(f1 instanceof Object); // --> trueCopy the code

When checking whether an instance belongs to a class, use Instanceof. Typeof can only detect variables of basic datatype, and has its own limitations. It cannot subdivide objects, arrays, and regees under Object.

All instances are Object datatypes, and the variable of each Object datatype is an instance of the built-in class Object, so f1 is also an instance of Object.

4.5. Detect private attributes

function Fn() {
    this.x = 100;
    this.getX = function () {
        console.log(this.x);
    };
}
var f1 = new Fn;
var f2 = new Fn;Copy the code

F1 and F2 are both instances of Fn, and both have x and geX attributes, but these two attributes are private, so:

console.log(f1.getX === f2.getX); // --> falseCopy the code
  • in: Checks whether an attribute belongs to the object,attr in objectIn is true for both private and public attributes, as long as they exist
console.log('getX' in f1); // --> trueIs one of its propertiesCopy the code
  • HasOwnProperty: Checks if a property is private to the object. This method checks only private properties
console.log(f1.hasOwnProperty('getX')); // --> true 'getX' is a private property of f1Copy the code

Think: Tests whether a property is a public property of the object

function hasPubProperty(obj, attr) {
    // If it is not a private property, it must be a public property
    return (attr inobj) && ! obj.hasOwnProperty(attr); }console.log(hasPubProperty(f1, 'getX'));Copy the code

Fifth, this


This comes up a lot, but let’s talk about this.

In JavaScript, this is mainly studied in functions, but this is not only in functions. The global this is window.

In JavaScript, this represents the body in which the action is being executed, and context in JavaScript represents the context in which the action is being executed.

Let’s be clear: who this is has nothing to do with where the function is defined or executed.

  • If the function name is preceded by a “.”, this is the name of the function. If not, this is the window.

  • This is always window in self-executing functions;

  • Binds a method to an event of an element. When the event is triggered, the corresponding method is executed. This in the method is the current element.

function fn() {
    console.log(this);
}
var obj = {
    fn:fn
};
fn(); // this -> window
obj.fn(); // this -> obj

document.getElementById('div1').onclick = fn; // this in fn is #div1
document.getElementById('div1').onclick = function () {
    // this -> #div1
    fn(); // this -> window
};Copy the code

Exercises:

function sum() {
    // this -> window
    fn();// this -> window
}
sum();Copy the code
var oo = {
    sum:function () {
        // this -> oo
        fn(); // this -> window}}; oo.sum();Copy the code