Schema summary of creating objects in JavaScript
**JavaScript creates object pattern:
Object literal
Factory model
Constructor mode
Prototype mode
Combining constructor and prototype pattern
Prototype dynamic mode
**
Most object-oriented languages have the concept of a class, through which multiple objects with the same methods and attributes can be created. Although technically, javascript is an object-oriented language, javascript does not have the concept of classes, everything is an object. Any object is an instance of a certain reference type and is created through existing reference types; the reference type can be native or customized.
1. Object literal
var person = { name : 'Nicholas'; age : '22'; job :"software Engineer" saysName: function() { alter(this.name); }}In the example, an object named person is created and three attributes (name, age, job) and a method (sayName()) are added to it. The sayName() method is used to display the value of this.name (resolved as person.name).
Object literals can be used to create a single object, but this method has an obvious disadvantage: creating many objects using the same interface will produce a lot of duplicate code.
2. Factory model
Factory pattern is a well-known design pattern in the field of software engineering. Factory pattern abstracts the process of creating specific objects and uses functions to encapsulate the details of creating objects with specific interfaces.
function createPerson(name,age,job){ var o = new object{}; o.name=name; o.age=age; o.job=job; o.sayName=function(){ alert(this.name); }; return o;}var person1=creatPerson("Nicholas",22,"software Engineer"); var person2=creatPerson("Greg",24,"student");The function creatPerson{} can build a Person object containing all the necessary information based on the accepted parameters. This function can be called countless times, and each time it will return an object containing three properties and one method.
Although the factory model solves the problem of creating multiple similar objects, it does not solve the problem of object recognition (i.e. how to know the type of an object).
3. Constructor mode
function Person(name,age,job) { this.name = name; this.age = age; this.job = job; this.sayName = function() { alert(this.name); }}//Create an instance of Person through the new operator var person1 = new Person("Nicholas",22,"software Engineer");var person2 = new Person("Greg",24,"student");person1.sayName(); //Nicholasperson2.sayName(); //GregThe difference from the factory model is
Create object not displayed
Assign attributes and methods directly to this object
No return statement
To create a new instance of Person, you must use the new operator. 4 steps to call the constructor:
Create a new object
Assign the scope of the constructor to a new object (this points to this new object)
Execute the code in the constructor
Return a new object
All objects created in this example are both instances of Object and Person instances. It can be verified by the instanceof operator.
alert(person1 instanceof Object);//true
The constructor pattern also has its own problems. In fact, the sayName method will be recreated once on each instance. It should be noted that the methods created by instantiation are not equal. The following code can prove that
alert(person1.sayName == person2.sayName);//false
This problem can be solved by moving the method outside the constructor as a global function.
function Person(name,age,job) { this.name = name; this.age = age; this.job = job; }function saysName() { alert(this.name); }Global functions created in the global world can actually be called by instances created by Person, which is a bit unrealistic; if the object needs to define a very correct method, then many global functions need to be defined, which lacks encapsulation.
4. Prototype mode
Each function created in JavaScript has a prototype property, which is a pointer to an object, containing properties and methods that can be shared by all instances of a specific type (let all object instances share its properties and methods)
function Person() {} Person.prototype.name ="Nicholas"; Person.prototype.age = 22; Person.prototype.job = "software Engineer"; Person.prototype.sayName(){ alert(this.name); }; var person1 = new Person(); person1.sayName(); //Nicholasalert(person1.sayName == person2.sayName);//trueThe above code does these things:
Define a constructor Person. The Person function automatically obtains a prototype property. This property only contains a constructor property pointing to Person by default.
Add three properties and one method through Person.prototype
Create an instance of Person, and then call the sayName() method on the instance
Using Person constructor and Person.prototype to create an instance as an example, to show the relationship between objects
Using Person constructor and Person.prototype to create an instance as an example, to show the relationship between objects
The figure shows the relationship between the Person constructor, Person's prototype properties, and two instances of Person. Person.prototype points to the prototype object, Person.prototype.constructor points back to Person. In addition to containing the constructor attribute, the prototype object also contains other properties and methods added later. Both Person's two instances person1 and person2 contain an internal property, which only points to Person.prototype.
The call process of the sayName() method:
Looking for the logName() method on the person1 instance, I found that there was no such method, so I traced back to the prototype of person1
Look for the sayame() method on the prototype of person1. There is this method, so the method is called
Based on such a search process, we can prevent the instance from accessing the same-name attribute on the prototype by defining the same-name attribute in the prototype on the instance. It should be noted that doing so will not delete the same-name attribute on the prototype, but will only prevent the instance from accessing.
function Person() {} Person.prototype.name ="Nicholas"; Person.prototype.age = 22; Person.prototype.job = "software Engineer"; Person.prototype.sayName(){ alert(this.name); }; var person1 = new Person(); var person2 = new Person(); person1.name="Greg"alert(person1.name) //Greg comes from the instance alert(person2.name) //Nicholas comes from the prototypeUse the delete operator to completely delete instance properties
delete person1.name;alert(person1.name) //Nicholas from the prototype
Use the hasOwnProperty() method to detect whether a property exists in an instance or a prototype
function Person() {} Person.prototype.name ="Nicholas"; Person.prototype.age = 22; Person.prototype.job = "software Engineer"; Person.prototype.sayName(){ alert(this.name); }; var person1 = new Person(); var person2 = new Person(); alert(person1,hasOwnProperty("name"));//false person1.name="Greg"alert(person1.name) //Greg From the instance alert(person1, hasOwnProperty("name"));//truealert(person2.name) //Nicholas From the prototype alert(person2, hasOwnProperty("name"));//false delete person1.name;alert(person1.name) //Nicholas From the prototype alert(person1, hasOwnProperty("name"));//falseThe following figure shows the relationship between instances and prototypes in different situations
Simple prototype syntax
function Person() {} Person.prototype={ name : "Nicholas", age : 22, job : "software Engineer", sayName: function(){ alert(this.name); } };In the above code, the constructor attribute no longer points to Person, and the type of the object cannot be determined through the constructor. You can set it back to the appropriate value like below
function Person() {} Person.prototype={ constructor:Person, name : "Nicholas", age : 22, job : "software Engineer", sayName: function(){ alert(this.name); } };Resetting the constructor property will cause its [[Enumerable]] property to be set to true. By default, the native constructor property is not enumerable. You can use the Object.defineProperty() method to change it.
Object.defineProperty(Person.prototype,"constructor",{ enumerable:false, value:Person});The process of finding values in a prototype is a search, and any modifications made by the prototype object can be reflected immediately from the instance.
var friend=new Person();Person.prototype.sayHi=function(){ alert("hi);}friend,sayHi();//"hi"(no problem)The person instance is created before adding a new method, but still has access to the newly added method because of the loose connection between the instance and the prototype
The situation after rewriting the prototype object
function Person() {}var friend=new Person(); Person.prototype={ name : "Nicholas", age : 22, job : "software Engineer", sayName: function(){ alert(this.name); } }; friend.sayName();//errorThe reason for the error when calling friend.sayName() is that the prototype pointed to by friend does not contain attributes named after this field, as shown in the figure below.
Prototype object problem
The prototype object omits the process of passing initialization parameters for the constructor, and all forces obtain the same attribute value by default. The biggest problem with prototype models is that they have their shared nature. When the prototype model contains attributes of reference type, the problem is more serious. Let’s take a look at the following example.
function Person() {} Person.prototype={ constructor:Person, name : "Nicholas", age : 22, job : "software Engineer", friends:["Shelby","Court"], sayName: function(){ alert(this.name); } }; var person1=new Person(); var person2=new Person(); person1.friend.push("Van"); alert(person1.friends);//"Shelby,Court,Van" alert(person2.friends);//"Shelby,Court,Van" alert(person1.friends==person2.friends);//true5. Combining constructor mode and prototype mode
In combination of constructor mode and prototype mode, constructors are used to define instance properties, and prototype models are used to define methods and shared properties. In this way, each instance will have its own copy of the instance attributes, and can also share references to methods, saving memory to the maximum extent.
function Person(name,age,job) { this.name = name; this.age = age; this.job = job; this.friends=["Shelby","Court"];}Person.prototype={ constructor: Person, sayName: function(){ alert(this.name); } }var person1=new Person("Nicholas",22,"software Engineer");var person2 = new Person("Greg",24,"student");person1.friend.push("Van"); alert(person1.friends);//"Shelby,Court,Van" alert(person2.friends);//"Shelby,Court" alert(person1.friends==person2.friends);//false alert(person1.sayName==person2.sayName);//true6. Dynamic prototype mode
The prototype dynamic mode encapsulates all the information required into the constructor, and uses the if statement to determine whether a certain property in the prototype exists. If it does not exist (when the constructor is called for the first time), execute the prototype initialization code inside the if statement.
function Person(name,age) { this.name = name; this.age = age; this.job =job;//Method if(typeof this.sayName != 'function') { Person.prototype.sayName = function() { alert(this.name); }; }}var friend = new Person('Nicholas','22','Software Engineer');//The constructor was called for the first time, and the prototype was modified at this time var person2 = new Person('amy','21');//The sayName() method already exists and the prototype will not be modified againRecommended reading:
Several common ways to create objects in js object-oriented (factory mode, constructor mode, prototype mode)
The above is the pattern of creating objects in JavaScript introduced to you by the editor. I hope it will be helpful to everyone!