Learning materials: JavaScript Advanced Programming
You can create objects either by creating an object instance and then adding properties to it, or by object literals. But if you want to create a large number of objects, these two methods can lead to a lot of duplicate code. To solve this problem, a variant of the factory model can be used:
1. Factory mode
Use a function to encapsulate the details of creating an object with a specific interface, such as the following:
function Createperson (name, age, Job) { var o=New Object (); O.name=name; O.age= Age; O.job=job; O.sayname=function() { alter (this. Name); } return o; } var person1=createperson ("Shirley", "software Engineer");
Factory mode solves the problem of creating multiple similar objects, but does not solve the problem of object recognition (that is, how to know the type of an object).
2. Constructor mode
Create a custom constructor that defines the properties and methods of the custom object. You can use the constructor to rewrite the above example as follows:
function Person (name, age, Job) { this. name=name; this. age= age; this. job=job; this. sayname=function() { alter (this. Name); } } var person1=New person ("Shirley", "software Engineer");
Compared to the factory model:
(1). There is no explicit creation of an object;
(2). Assign properties and methods directly to the This object
(3). No Return statement
Also, note that the function name of the constructor is capitalized in the first letter, and the new operator is used when creating an instance of person. Calling the constructor with new will actually go through four steps:
(1). Create a new object
(2). Assigns the scope of the constructor to the new object (therefore, this points to the new object)
(3). Call the code in the constructor to assign properties and methods to the new object
(4). return new Object
Therefore, Person1 is an instance of person and Person1.constructor=person.
The constructor property of an object is initially used to identify the object type, but the object type is detected and is more reliable with the instanceof operator:
// true // true
Therefore, creating a custom constructor can identify its instance as a specific type in the future. Note that all objects are inherited from object.
2.1 Problems with constructors
The main problem with constructors is that each method is recreated on each instance. Because a function is also an object, each definition of a function is an instantiation of an object, so, logically, the constructor can also be defined as follows:
function Person (name, age, Job) { this. name=name; this. age= age; this. job=job; this. sayname=new Function ("Alter (THIS.NAME)"); var person1=New person ("Shirley", "software Engineer");
In order to solve this problem, it is possible to use prototype mode
3. Prototype mode
Each correspondence we create has a prototype attribute, which is a pointer to an object. The purpose of this object is to include properties and methods that can be shared by all instances of a particular type. The benefits of using a prototype object allow all object instances to share its properties and methods. The previous example uses a prototype model to write:
function Person () {}person.prototype.name=Shirley; Person.prototype.age=18; Person.prototype.job="Software Engineer"; Person.prototype.sayName=function() { alter (this. name);} var person1=New person ();
The above method of creation, each add a property and method to type Person.prototype.XX again, in order to reduce unnecessary input, but also to visually better encapsulate the functionality of the prototype, it is more common to use an object containing all the properties and methods of the literal to rewrite the entire prototype object.
function Person () {}person.prototype={ name: ' Shirley ', age :, job: ' Software Engineer ', Sayname: function () { alter (this. Name); }} ; var person1=New person ();
In the preceding code, Person.prototype is set to a new object created as an object literal. The final result is consistent with the creation method above, but with one exception: the constructor property no longer points to person. Each time a function is created, its prototype object is created, and the object is automatically given the constructor property. The above syntax, in essence, overrides the default prototype object, so the constructor property becomes the constructor zodiac of the new object (pointing to the object constructor). However, Person1 instanceof person will still return true
If constructor is important, you can set it up in the following ways. In this case, however, the [[Enumerable]] attribute of the constructor property is set to True, and by default the native constructor is not enumerable and can be set using the Object.defineproperty () method.
function Person () {}person.prototype={ Constructor:person, name: ' Shirley ', age : job: "Software Engineer", sayname:function() { alter (this). name);} } ; var person1=New person ();
Note that the values in the prototype can be accessed through an object instance, but the values in the prototype cannot be overridden through an object instance. If you add an attribute to the instance with the same name as a property in the prototype, we create the property in the instance that masks that property in the prototype. However, if a property that contains a reference type is manipulated by an instance, it is possible that the data in the prototype will change because the array exists in the prototype instead of the instance. See the example below
function person () {}person.prototype ={Constructor:person, Name: "Shirley", Age: 18, job: "Software Engineer", friends:[ ' A ', ' B ' function this .name); }}; var person1=new person (); var person2=new person ();p Erson1.friends.push ( ' C ' // "A,b,c"
So few people use prototype mode alone.
4. Combining the constructor pattern with the prototype mode
The most common way to create custom types is to combine the constructor pattern with the prototype pattern. The constructor pattern is used to define instance properties, and the prototype schema is used to define methods and shared properties. This blending mode also supports passing parameters to constructors.
functionPerson (name,age,job) { This. name=name; This. age=Age ; This. job=job; This. friends=[' A ', ' B '];} Person.prototype={Constructor:person, sayname:function() {Alter ( This. Name); }};varperson1=NewPerson ("Lily", "Doctor"); varPerson2=NewPerson ("Emma", "Student");p Erson1.friends.push (C); alert (person2.friends); //"A, B"
5. Dynamic Prototyping Mode
The dynamic prototype pattern is to encapsulate all information in the constructor, while preserving the advantages of using constructors and prototypes while initializing the prototype in the constructor (only if necessary).
functionPerson (name,age,job) { This. name=name; This. age=Age ; This. job=job; This. friends=[' A ', ' B ']; if(typeOf This. sayname! = "function") {Person.prototype.sayName=function() {Alter ( This. Name); }; }} varperson1=NewPerson ("Lily", "Doctor");
The IF statement can be used to check for any property or method that should exist after initialization, without having to check each one. For objects created with this pattern, you can also use the instanceof operator to determine its type. It should be noted, however, that the prototype cannot be rewritten in the form of object literals.
6. Parasitic constructor mode
The basic idea is to create a function that simply encapsulates the code that creates the object, and then returns the newly created object.
function Person (name, age, Job) { var o=New Object (); O.name=name; O.age= Age; O.job=job; O.sayname=function() { alter (this. Name); } return o; } var New Person ("Shirley", "software Engineer");
This pattern is exactly the same as the factory pattern, except that the new operator is used and the wrapper function is called a constructor function. Note that the object returned is not related to the constructor or the prototype of the constructor, and cannot be determined by the instanceof operator.
7. Secure constructor Mode
A prudent object is one that does not have a public attribute and its methods do not refer to the object of this, which is best suited for use in some secure environments where this and new are forbidden or when data is altered by other applications. The secure constructor is similar to the parasitic constructor pattern, but the following two points are different, one is that the instance method of the newly created object does not refer to this and the second is that the constructor is not applicable to the new operator. (not very well understood)
JavaScript Create objects