This is the fourth day of my participation in the August More text Challenge. For details, see: August More Text Challenge

The factory function

A factory pattern is a design pattern that is simply a function that creates an object, adds properties and methods to it, and then returns the object. Just like a factory, you can batch produce certain types of objects. This design pattern is designed to reduce code redundancy.

Let me just write a little example

  function createPerson(name, age) {
        let o = new Object(a); o.name = name; o.age = age; o.sayName =function () {
            console.log(this.name);
        };
        return o;
    }
    let person1 = createPerson("jackson".20);
    let person2 = createPerson("bear".22);
    person1.sayName(); //jackson
    person2.sayName(); //bear
Copy the code

Here the createPerson() function takes two arguments from which it builds an object containing information about the person. The main reason for this is to create a large number of objects that have overlapping properties, and if each one is new, then add the properties one by one. It’s also a tiring job. In the code above, we declare a createPerson method that can be manufactured in batches. The downside, however, is that it does not address the issue of object identification (what type of object is being created).

The constructor

The constructor pattern allows you to customize reference types. You can use the new keyword to create an instance of a built-in type to create an instance of a custom type. We often use new Vue(), which essentially instantiates a Vue object by passing options.

The above factory function can be improved with the constructor

    function Person(name, age) {
        this.name = name;
        this.age = age;
        this.sayName = function () {
            console.log(this.name);
        };
    }
    let person1 = new Person("jackson".20);
    let person2 = new Person("bear".22);
    person1.sayName(); // jackson
    person2.sayName(); // bear
Copy the code

In this example, we can see that constructors can replace factory functions, and in real development, we usually use constructors more often than we use factory functions.

Note: By convention, the first letter of the constructor name is capitalized

To create a new instance of Person, you must use the new operator. Calling the constructor in this way actually takes five steps.

(1) Create an object in memory.

(2) The Prototype property inside the new object is assigned to the constructor’s Prototype property.

(3) This inside the constructor is assigned to the new object (i.e. this refers to the new object).

(4) Execute the code inside the constructor (adding properties to the new object).

(5) If the constructor returns a non-empty object, return that object; Otherwise, the newly created object is returned.

Constructors are good, but there are some problems. Let’s take a look at the logic

In the example above, person1 and Person2 both have a sayName() method, but they are not the same function instance, so the method sayName() defined here will be created on each instance, which is easy for us but not for the machine.

        this.sayName = function () {console.log(this.name); };// The logical equivalent is the following
        this.sayName = new Function("console.log(this.name)"); 
Copy the code

To optimize the

Since we’re doing the same thing, there’s no need to define two different instances of Function, we can just move the Function definition outside of the constructor.

    function Person(name, age) {
        this.name = name;
        this.age = age;
        this.sayName = sayName;
    }

    function sayName() {
        console.log(this.name);
    }
    let person1 = new Person("jackson".20);
    let person2 = new Person("bear".22);
    person1.sayName(); // jackson
    person2.sayName(); // bear
Copy the code

Here, sayName() is defined outside the constructor. Inside the constructor, the sayName attribute is equal to the global sayName() function. Because this time the sayName attribute contains only a pointer to an external function, person1 and Person2 share the sayName() function defined at the global scope. This solves the problem of having functions with the same logic repeatedly defined, but it also messes up the global scope because that function can actually only be called on one object. If the object requires multiple methods, then multiple functions are defined at the global scope. This can cause code referenced by custom types to not aggregate well. This new problem can be solved with a prototype pattern.

We will talk about prototypes next time (please mark my article, thank you)