Analysis of various pattern _ javascript techniques for creating objects in javascript

Source: Internet
Author: User
Tags hasownproperty
The following small series will give you an analysis of various methods for creating objects in javascript. I think it is quite good. Now I will share it with you and give you a reference. Let's take a look at the javascript advanced programming recently (version 2)

Create an object in javascript

• Factory Model

• Constructor Mode

• Prototype

• Constructor and prototype

• Prototype dynamic mode

Most object-oriented languages have the concept of a class. You can create multiple objects with the same methods and attributes through the class. Although technically speaking, javascript is an object-oriented language, javascript has no class concept and everything is an object. Any object is an instance of a reference type and is created through an existing reference type. The reference type can be native or custom. Native reference types include Object, Array, Data, RegExp, and Function. ! A reference type is a data structure that organizes data and functions together. It is usually called a class. In javascript, which lacks the class concept, the problem to be solved is how to efficiently create objects.

1.1.0. General method for creating an object

Var person = {}; // literal representation of the object, equivalent to var person = new Objcect (); person. name = 'evansdiy '; person. age = '22'; person. friends = ['ajiao', 'tiantian ', 'pangzi']; person. logName = function () {console. log (this. name );}

An Object is created based on the Object reference type. The Object contains four attributes, one of which is a method. If you need many person-like instances, there will be a lot of repeated code.

1.1.1. Factory model [top]

Create an object by using a function that contains the object details, and then return this object.

function person(name,age,friends) {  var o = {    name: name,    age: age,    friends: friends,    logName: function() {      console.log(this.name);    }  };  return o;}var person1 = person('Evansdiy','22',['ajiao','tiantian','pangzi']);

Every time you call the person function, a new object is created through the object o in the function, and then returned. In addition, this internal object o exists for the purpose of creating a new object has no other purpose. In addition, the type of the object created in factory mode cannot be determined.

1.1.2. constructor mode [top]

Function Person (name, age, job) {this. name = name; this. age = age; this. job = job; this. logName = function () {console. log (this. name) ;}} // create an instance var person1 = new Person ('boy-A', '22', 'worker') for the Person using the new operator '); var person2 = new Person ('Girl-B ', '23', 'teacher'); person1.logName (); // boy-aperson2.logName (); // girl-

Compared with the factory mode, we can find that there is no need to create an intermediate object and no return. In addition, you can identify the constructor instance as a specific type, which solves the problem of Object Recognition (by checking the constructor attribute of the instance, or use the instanceof operator to check whether the instance is created by a constructor ).

Console. log (person1.constructor = Person); // The constructor is located in the constructor prototype and points to the constructor. The result is true.

Console. log (person1 instanceof Person); // use the instanceof operator to determine whether person1 is an instance of the Person constructor, but the constructor mode also has its own problems. In fact, the logName method is re-created on each instance. Note that the method created by instantiation is not equal. The following code returns false:

Console. log (person1.logName = person2.logName); // false we can move the method outside the constructor (to a global function) to solve this problem:

function logName() {  console.log(this.name);}function logAge() {  console.log(this.age);}

However, the global functions created in the global environment can only be called by instances created by Person, which is a bit non-real. If there are many methods, you need to define them one by one, without encapsulation.

1.1.3. prototype mode [top]

Every function in javascript contains a pointer to the prototype attribute (most browsers can access it through the internal attribute _ proto _). The prototype attribute is an object, it contains the attributes and Methods shared by all instances created by a reference type.

function Person() {}Person.name = 'evansdiy';Person.prototype.friends = ['ajiao','jianjian','pangzi'];Person.prototype.logName = function() {  console.log(this.name);}var person1 = new Person();person1.logName();//'evansdiy'

The above Code does the following:

1. A constructor Person is defined. The Person function automatically obtains a prototype attribute. By default, this attribute contains only one constructor attribute pointing to the Person;

2. Use Person. prototype to add three attributes, one of which serves as a method;

3. Create a Person instance and then call the logName () method on the instance.

Note the call process of the logName () method:

1. Find the logName () method on the person1 instance. If this method is not found, it is traced back to the prototype of person1.

2. this method is used to search for the logame () method on the prototype of person1. Therefore, based on this search process, we can define the attributes of the same name in the prototype on the instance, to prevent the instance from accessing the properties of the same name on the prototype. It is worth noting that this will not delete the properties of the same name on the prototype, but will only block instance access.

Var person2 = new Person ();

Person2.name = 'laocai'; if you no longer need attributes on the instance, you can delete them using the delete operator.

Delete person2.name; Use the for-in loop to enumerate all attributes that an instance can access (whether in an instance or a prototype ):

for(i in person1) {  console.log(i);}

At the same time, you can also use the hasOwnProperty () method to determine whether a property exists on the instance or in the prototype. Only when the property exists in the instance will true be returned:

Console. log (person1.hasOwnProperty ('name'); // true! HasOwnProperty comes from the Object prototype. It is the only method in javascript that does not search for the prototype chain when processing attributes. [Via javascript secret garden] You can also use the in operator and hasOwnProperty () method to determine whether an attribute exists in the instance or in the prototype:

Console. log ('ds Ds' in person1 )&&! Person1.hasOwnProperty ('ds Ds'); first, judge whether person1 can access the friends attribute. If so, determine whether this attribute exists in the instance (note the previous one !), If the property does not exist in the instance, it indicates that the property exists in the prototype. As mentioned above, prototype is also an object, so we can use the literal representation of the object to write the prototype. The Code previously added to the prototype can be changed:

Person.prototype = {  name: 'evansdiy',  friends: ['ajiao','jianjian','pangzi'],  logName: function() {    console.log(this.name);  }}

Because the Object literal syntax overwrites the entire prototype, the constructor attribute obtained by default when the original constructor is created will point to the Object constructor:

// After the prototype of the object literal is rewritten

Console. log (person1.constructor); // However, the instanceof operator still returns the expected result:

// After the prototype of the object literal is rewritten

Console. log (person1 instanceof Person); // true of course, You can manually set the constructor value in the prototype to solve this problem.

Person.prototype = {  constructor: Person,  ......}

If the prototype object is modified after the object instance is created, the modifications to the prototype are immediately reflected in all object instances:

function Person() {};var person1 = new Person();Person.prototype.name = 'evansdiy';console.log(person1.name);//'evansdiy'

The connection between the instance and the prototype is just a pointer, rather than a copy of the prototype. The prototype is actually a search process, any modifications made to the prototype object will be reflected in all object instances, even if the prototype is modified after the instance is created. What if the prototype object is rewritten after the object instance is created?

Function Person () {}; var person1 = new Person1 (); // The created instance references the original prototype. // The prototype Person is rewritten. prototype = {friends: ['ajiao', 'jianjian ', 'pangzi']} var person2 = new Person (); // This instance references the new prototype console. log (person2.friends); console. log (person1.friends );

When the above code is executed to the last line, there will be an undefined error. If we use the for-in loop to enumerate the accessible attributes in person1, we will find that there is nothing in it, however, person2 can access the DS attribute on the prototype. ! The rewriting prototype disconnects the existing prototype from all the previously created object instances. The prototype of the previously created object instance is still in use, but it is old.

// When creating person1, the prototype object has not been overwritten. Therefore, the constructor in the prototype object is still the default Person ()

Console. log (person1.constructor); // Person ()

// But the constructor of person2 points to Object ()

Console. log (person2.constructor); // Object () You must note that the prototype mode ignores the process of passing parameters for the constructor, and all instances obtain the same attribute values. At the same time, there is still a major problem in the prototype mode, that is, the reference type value in the prototype object will be shared by all instances and the modification of the reference type value will be made, it is also reflected in all object instances.

function Person() {};Person.prototype = {  friends: ['ajiao','tiantian','pangzi']}var person1 = new Person();var person2 = new Person();person1.friends.push('laocai');console.log(person2.friends);//['ajiao','tiantian','pangzi','laocai']

Modify the reference type value of person1 friends, which means that the friends in person2 will also change. In fact, the friends stored in the prototype is actually a pointer to the friends value in the heap (the pointer length is fixed and saved in the stack). When an instance accesses the reference type value through the prototype, it is also a pointer-based access, rather than accessing the copies on the respective instances (such copies do not exist ).

1.1.4. Create an object using constructor and prototype [top]

Combining the advantages of constructor and prototype mode, the constructor can be used to pass initialization parameters, define instance attributes, and define public methods and public attributes using prototype, this mode is most widely used.

function Person(name,age) {  this.name = name;  this.age = age;  this.friends = ['ajiao','jianjian','pangzi'];}Person.prototype = {  constructor: Person,  logName: function() {    console.log(this.name);  }}var person1 = new Person('evansdiy','22');var person2 = new Person('amy','21');person1.logName();//'evansdiy'person1.friends.push('haixao');console.log(person2.friends.length);//3

1.1.5. Prototype dynamic mode [top]

The prototype dynamic mode encapsulates all required information into the constructor, and uses the if statement to determine whether an attribute in the prototype exists. if it does not exist (when this constructor is called for the first time ), execute the prototype initialization code in the if statement.

Function Person (name, age) {this. name = name; this. age = age; if (typeof this. logName! = 'Function') {Person. prototype. logName = function () {console. log (this. name) ;}; Person. prototype. logAge = function () {console. log (this. age) ;};}}var person1 = new Person ('evansdiy ', '22'); // the first time the constructor is called, the prototype var person2 = new Person ('amy ', '21') is modified. // The logName () method already exists and the prototype will not be modified.

Note that this mode cannot use the object literal syntax to write the prototype object (this will overwrite the prototype object ). If the prototype is rewritten, the prototype objects that can be accessed by the First Instance created by the constructor do not contain the attributes of the prototype objects in the if statement.

Function Person (name, age) {this. name = name; this. age = age; if (typeof this. logName! = 'Function') {Person. prototype = {logName: function () {console. log (this. name) ;}, logAge: function () {console. log (this. age) ;}};}var person1 = new Person ('evancediy ', '22'); var person2 = new Person ('amy', '21 '); person2.logName (); // 'amy 'person1. logName (); // The logName () method does not exist

It should be noted that each model has its own application scenario, which does not matter.

The above analysis of the various methods for creating objects in javascript is all the content shared by the editor. I hope to give you a reference, and I hope you can support the script house a lot.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.