SoFunction
Updated on 2025-03-08

Several ways to create objects in JavaScript and the problem of this pointing

Factory model

Factory mode is generally used to abstractly create specific objects, and is the way to create objects according to specific interfaces.

function createPerson(name, age) {
    let o = {};
     = name;
     = age;
     = function() {
        (`${} is studying`)
    }
    return o
}
const p1 = createPerson('Zhang San', 18)
const p2 = createPerson('Li Si', 20)
() // Zhang San is studying

It is worth mentioning that ifcreatePersonIn the function,Change to arrow function, then the printed this will change, because the arrow function has occurredthisThe problem pointed to.

Advantages of the factory model:existcreatePersonIn  , the factory function can be called multiple times with different parameters, and each time it returns an object containing a specific parameter and a method. It can solve the problem of creating multiple similar objects.

Disadvantages of the factory model:

  • 1. The object identification problem was not resolved.
  • 2. Every time an object is created, a public method is created, and the method is also an object, which causes memory waste.

Constructor mode

In JS, constructors are used to create objects of a specific type. pictureObjectArraySuch native constructed objects can be run directly in the execution environment when running. Of course, you can also customize the constructor and define properties and methods for your own object type in the form of a function.

function Student(name, age) {
     = name;
     = age;
     = function() {
        (`${} is studying`)
    }
}
const p1 = new Student('Zhang San', 18)
const p2 = new Student('Li Si', 20)

Through the above code, the same effect as the factory mode can be achieved. But it is worth noting: IfstudyThe function becomes an arrow function,thisThe direction of  will not change.

Like the above code, if the constructor is called, you must usenewKeywords, in this process, the constructor will do four things:

  • Create a new object in memory
  • Implicit prototype of this new object__proto__The display prototype assigned to this constructorprototype
  • The internal constructorthisAssigned as this new object (add new attributes to the new object)
  • Execute the code in the constructor and determine whether there is an object's return value. If it exists, it returns this return value, otherwise it returns this new object.
  • Advantages and disadvantages of constructors: First, the constructor solves the problem of object identification, but if there is a function in the constructor, every time an instance is created, it is equivalent to the function being recreated, because in JS, functions are also equivalent to objects, causing waste of space.

About this

In standard functions, this refers to treating a function as a context object for method calls, which is often called this at this time.

As we mentioned above, if an arrow function appears inside the factory pattern and the constructor pattern, thenthisThe pointing of   will be different, because it does not exist in the arrow functionthis, in the arrow functionthisThe context that defines the function will be preservedthisWhich object to refer to must be called before it will be determined, in factory mode, although(), make calls, but since there is no inside the arrow functionthis, so search upwards and findfunction createPersonFunction, bindingwindow, and in the constructor mode this is assigned to this new object, which is equivalent to the arrow functionthis, is this new object, that is, the subsequent instance.

Perhaps, through the above description, many students still don’t understand this in the arrow function below, and the context that defines the function is not well understood. I will give an example.

// Factory modefunction createPerson(name, age) {
    let o = {};
     = name;
     = age;
     = () => {
        (`${} is studying`)
    }
    return o
}

const obj = {
    name: 'Zhang San'
}

const p1 = (obj, 'Li Si', 20) // createPerson binds obj, then the arrow function will also bind obj() // So the output here is Zhang San is studying,Instead undefined

Prototype mode

Each function will create oneprototypeAttribute, this attribute is an object that contains properties and methods that should be shared by instances of a specific reference type. In fact, this object is the prototype of the object created by calling the constructor. The advantage of using a prototype object is that the properties and methods defined on it can be shared by object instances. It turns out that the value assigned to the object instance directly in the constructor can be assigned to their prototype directly.

function Student() {}
 = 'Zhang San';
 = 20;
 = ['ls', 'ww'];
 = function() {
    (`${} is studying`)
}

const p1 = new Student()
const p2 = new Student()

Created from abovep1, p2, sharedStudentProperties on the prototype are equivalent to creating two different objects with the same attributes. Similarly, if the abovestudyChange it into an arrow function, everyone should knowthisWho is bound to? (Tip: new and display bindings cannot be used at the same time)

Pros and cons of prototype mode:First of all, the prototype mode solves the problem of space waste caused by the previous two modes, but their attributes are shared, so generally speaking, the prototype mode will not be used separately.