This is the third day of my participation in Gwen Challenge

Preface:

As a front-end person, ECMAScript (JavaScript) is the language we eat. It’s enough for our daily work, but we have to keep learning and understanding. So I opened JavaScript Advanced Programming (4th Edition), and this time, I have a deeper understanding of object creation, which I share with you here!

The basic introduction of ECMAScript objects, as well as the creation of MDN and various tutorials and books, is well covered here. On dry

An overview of the

ECMAScript 6 officially supports classes and inheritance. The classes in ES6 are designed to fully cover the prototype-based inheritance pattern designed by the previous specification. However, for all intents and purposes, ES6 classes are just syntactic sugar that encapsulates ES5.1 constructors and archetypal inheritance. Here, we share the basics of object creation, both in depth and in depth!

The factory pattern creates objects

What is the factory model?

The factory pattern encapsulates the process of creating objects. It’s a lot like when we go to a restaurant and order, for example, scrambled eggs with tomatoes. We don’t care about how the tomatoes are cut or the eggs are beaten. We only care about the dish that is put on the table. In the factory mode, the process I pass in is ordering food, and the logic running in the factory function is equivalent to the part of the work that the cook and the waiter do — we don’t need to care about this part of the work, as long as we can get the result of the instance delivered to us by the factory.

  • The purpose of factory mode is to achieve no brain transfer, is to cool!

// Factory mode creates objects
function createPerson (name,age,job) {
    let o = new Object()
    o.name = name
    o.age = age
    o.job = job
    o.sayJob = function (){
        console.log(o.job);
    }
    return o
}

let person1 = createPerson("jack"."28"."996 Blessing Master")

person1.sayJob() // "996 Good Luck Master"
let person2 = createPerson("pony"."28"."Wangzhe Pesticide Professional Master")


person2.sayJob() // "king pesticide professional master"
Copy the code

Here, the function createPerson() takes three parameters from which an object containing The Person information is built. This function can be called multiple times with different arguments, each time returning an object containing three properties and one method. While this factory pattern solves the problem of creating multiple similar objects, it does not solve the problem of object identification (what type the newly created object is).

The constructor pattern creates objects

Constructors in ECMAScript are used to create objects of a specific type. Native constructors such as Object and Array can be used directly by the runtime in the execution environment. You can also customize constructors that define properties and methods for your own object types in the form of functions. For example, the previous example using the constructor pattern could be written as follows:

// Constructor mode
function Person (name,age,job) {
    this.name = name
    this.age = age
    this.job = job
    this.sayJob = function () {
        console.log(this.job);
    }
    // the logical equivalent of
    // this.sayJob = new Function ("console.log(this.job)")
}
let person1 = new Person("jack"."28"."996 Blessing Master")
person1.sayJob() // "996 Good Luck Master"


let person2 = new Person("pony"."28"."Wangzhe Pesticide Professional Master")
person2.sayJob() // "king pesticide professional master"

Copy the code

The Person() constructor replaces the createPerson() factory function. In fact, the code inside Person() is basically the same as that inside createPerson(), with the following differences.

  • No object is explicitly created.

  • Properties and methods are assigned directly to this.

  • There is no return.

To create an instance of Person, use the new operator. Calling the constructor in this way does the following.

  1. Create a new object in memory.
  2. The [[Prototype]] property inside this new object is assigned to the constructor’s Prototype property.
  3. This inside the constructor is assigned to the new object (that is, this refers to the new object).
  4. Executes the code inside the constructor (adding attributes to the new object).
  5. If the constructor returns a non-empty object, that object is returned; Otherwise, the newly created object is returned.

Each Object in the previous example is an instance of Object, as well as an instance of Person.

console.log( person2 instanceof Person);  // true
console.log( person2 instanceof Object);	// true
Copy the code

2. Constructors, while useful, are not without their problems. The main problem with constructors is that they define methods that are created on each instance. So for the previous example, person1 and person2 both have methods named sayName(), but they are not the same Function instance. As we know, functions in ECMAScript are objects, so each time a function is defined, an object is initialized. Logically, the constructor actually looks like this:

// Constructor mode
function Person (name,age,job) {
    this.name = name
    this.age = age
    this.job = job
    // the logical equivalent of
    this.sayJob = new Function ("console.log(this.job)")}Copy the code

But the mechanism for creating new Function instances is the same. Therefore, functions on different instances are not equal even though they have the same name, as follows:

console.log(person1.sayJob == person2.sayJob) // false

So there’s no need to define two different instances of Function. Furthermore, this can defer the binding of functions to objects until runtime.

// Solution 1: Move the function definition outside the constructor
function Person (name,age,job) {
    this.name = name
    this.age = age
    this.job = job
    this.sayJob = sayJob
}
sayJob = function () {
    console.log(this.job);
}

Copy the code

Here, sayJob() is defined outside the constructor. Inside the constructor, the sayJob attribute is equal to the global sayJob() function. Because this time the sayJob attribute contains only a pointer to an external function, person1 and person2 share the sayJob() function defined on the global scope. This solves the problem of repeating functions defined with the same logic, but it also messes up the global scope because that function can really only be called on one object. If the object requires multiple methods, define multiple functions in the global scope. This results in code that doesn’t cluster well for custom type references. This new problem can be solved by prototyping patterns.

The prototype pattern creates objects

Each function creates a Prototype property, which is an object containing properties and methods that should be shared by instances of a particular reference type. In effect, this object is a prototype of the object created by calling the constructor. The advantage of using a stereotype object is that the properties and methods defined on it can be shared by the object instance.

// Solution 2: Prototype

function Person () {}
Person.prototype.name = "xcb"
Person.prototype.sayJob = function () {
    console.log(this.job)
}

sayJob = function () {
    console.log(this.name + this.doing);
}

let person1 = new Person()
person1.name = "Lily"
person1.job = "student"
person1.sayJob()
Copy the code

conclusion

Well, today’s content is over here, thank you 🙏 everyone to watch, if you like, please give me a thumbs-up!

Author: chenuvi

Email address: [email protected]