There are many ways to create objects in JavaScript. Single objects can be created through the Object constructor or object literal. Obviously, these two methods will produce a large amount of duplicate code and are not suitable for mass production.
Next, we will introduce seven very classic ways to create objects, and they also have their own advantages and disadvantages.
1. Factory model
This factory function can be called countless times, each time it returns an object containing two properties and a method.
Although the factory pattern solves the problem of creating multiple similar objects, it does not solve the object recognition problem, that is, the type of an object cannot be known.
function createPerson(name, job) { var o = new Object(); = name; = job; = function() { (); } return o; } var person1 = createPerson('Mike', 'student'); var person2 = createPerson('X', 'engineer');
2. Constructor mode
function Person(name, job) { = name; = job; = function() { (); } } var person1 = new Person('Mike', 'student'); var person2 = new Person('X', 'engineer');
If the creation object is not displayed, use new to call this constructor. After using new, the following operations will be automatically performed:
① Create a new object;
② Assign the scope of the constructor to a new object (so this points to this new object);
③Execute the code in the constructor (add attributes to this new object);
④Returns the new object.
Disadvantages: Each method must be recreated on each instance.
It is indeed not necessary to create two Function instances that complete the same task. Besides, with this object, you don't need to bind the function to a specific object before executing the code. It can be defined in this form:
function Person( name, age, job ){ = name; = age; = job; = sayName; } function sayName(){ alert( ); }
In this way, the definition of the sayName() function can be transferred to outside the constructor. And inside the constructor, we set the sayName property to the global sayName() function. In this way, since sayName() contains a pointer to a function, person1 and person2 objects can share the same sayName() function defined in the global scope.
This solves the problem of two functions doing the same thing, but a new problem comes again: functions defined in the global scope can only be called by a certain object, which makes the global scope a little unreal. What's more important is: if the object needs to define many methods, then it needs to define many global functions. In this way, the reference type we customize is without any encapsulation.
These problems can be solved by using prototype patterns.
3. Prototype mode
Add information directly to the prototype object.
The advantage of using a prototype is that all instance objects can share the properties and methods it contains. Instead of defining object instance information in the constructor, this information can be added directly to the prototype object.
function Person() { } = 'Mike'; = 'student'; = function() { () } var person1 = new Person();
Ⅰ Understand the prototype
Whenever a new function is created, a prototype property is created for the function according to a specific set of rules.
By default, all prototype properties will automatically obtain a constructor property, which contains a pointer to the function where the prototype property resides.
Whenever the code reads a certain property of an object, a search will be performed, with the goal of the attribute with the given name. The search starts with the object instance itself. If an attribute with the given name is found in the instance, the value of the attribute is returned; if not found, continue to search for the prototype object pointed to by the pointer, and look for the attribute with the given name in the prototype object. If this property is found in the prototype object, the value of the property is returned.
Although the values saved in the prototype can be accessed through the object instance, the values stored in the prototype cannot be rewrited through the object instance.
If we add a property to the instance and the property has the same name as an attribute in the instance, then the property will be created in the instance, and the property will block the property in the prototype.
Even if the property is set to null, the property value in the instance is null.
However, using the delete operator allows you to completely delete the instance attributes, allowing you to revisit the properties in the prototype.
Use the hasOwnProperty() method to detect whether a property exists in an instance or in a prototype. This method will return true only when the given attribute exists in the object instance.
Ⅱ Prototype and in operator
The in operator returns true when a given property can be accessed through an object, whether the property exists in the instance or in the prototype.
Ⅲ Simpler prototype syntax
function Person(){ } = { name : "Mike", age : 29, job : "engineer", syaName : function(){ alert( ); } };
In the above code, set to equal to a new object created as an object literal. The end result is the same, with one exception: the constructor property no longer points to Person.
4. Use constructor mode and prototype mode in combination
Combining constructor patterns and prototype patterns is the most widely used and most recognized method of creating custom types.
It can solve the disadvantages of the above patterns. Using this pattern allows each instance to have its own copy of the instance attribute, but at the same time it shares a reference to the method. In this way, even if the instance attributes modify the value of the reference type, the attribute values of other instances will not affect the attribute values. It also supports passing parameters to the constructor, which can be said to be the advantage of the set two modes.
function Person(name) { = name; = ['Jack', 'Merry']; } = function() { (); } var person1 = new Person(); var person2 = new Person(); ('Van'); (); //["Jack", "Merry", "Van"] (); // ["Jack", "Merry"] ( === ); //false
5. Dynamic prototype mode
The dynamic prototype mode encapsulates all information in the constructor. When initializing, you can determine whether the prototype needs to be initialized by detecting whether a method that should exist is effective.
function Person(name, job) { // Attributes = name; = job; // method if(typeof !== 'function') { = function() { () } } } var person1 = new Person('Mike', 'Student'); ();
It will only be added to the prototype if the sayName() method does not exist. This code will only be executed when the constructor is first called. After that, the prototype has been initialized and there is no need to make any modifications. The modifications made to the prototype can be immediately reflected in all instances.
Secondly, the if statement can check any attribute or method that should exist after initialization, so there is no need to use a lot of if statements to check each attribute and method, just check one.
6. Parasitic constructor pattern
The basic idea of this pattern is to create a function, and the function only serves to encapsulate the code that created the object and then return the newly created object.
function Person(name, job) { var o = new Object(); = name; = job; = function() { () } return o; } var person1 = new Person('Mike', 'student'); ();
This pattern, except using the new operator and calling the wrapper function used a constructor, is almost the same as the factory pattern.
If the constructor does not return an object, it will also return a new object by default. By adding a return statement at the end of the constructor, the value returned when calling the constructor can be overridden.
7. Stable constructor mode
First of all, we understand that a safe object refers to no public attributes, and its method does not refer to this. Stable objects are best suited for use in some secure environments (this and new is prohibited) or when data is changed by other applications.
The safe constructor pattern is similar to the parasitic pattern, with two differences:
1. The instance method of creating an object does not refer to this;
2. Do not use the new operator to call the constructor.
function Person(name, job) { var o = new Object(); = name; = job; = function() { (name) //Note that there is no "this" here; } return o; } var person1 = Person('Mike', 'student'); ();
Like the parasitic constructor pattern, the objects created in this way have no relationship with the constructor, and the instanceof operator has no meaning to them.
The above is the detailed content shared by seven classic ways to create objects in JavaScript. For more information about creating objects in JavaScript, please pay attention to my other related articles!