A brief analysis of various patterns _javascript techniques for creating objects in JavaScript

Source: Internet
Author: User
Tags hasownproperty

I've been watching JavaScript Advanced Programming (second Edition).

Creation of objects in JavaScript

• Factory model

• constructor pattern

• Prototype mode

• Combining constructors and prototype patterns

• Prototype dynamic model

Most object-oriented languages have the concept of a class that allows you to create multiple objects with the same methods and properties. While JavaScript is technically an object-oriented language, JavaScript has no concept of class, and everything is an object. Any object is an instance of a reference type that is created from an existing reference type, or a reference type that can be native or custom. Native reference types are: Object, Array, Data, REGEXP, Function.! A reference type is a data structure that is organized together, often referred to as a class. In the absence of class-concept JavaScript, the problem that needs to be solved is how to create objects efficiently.

1.1.0. General method of creating objects

var person = {}; Object literal representation, equivalent to var person = new Objcect ();

Person.name = ' Evansdiy ';
Person.age = ' all ';
Person.friends = [' Ajiao ', ' Tiantian ', ' Pangzi '];
Person.logname = function () {
  console.log (this.name);
}

Based on the object reference type, an object is created that contains four properties, one of which is the method. If you need a lot of instances like person, there will be a lot of duplicate code.

1.1.1. Factory mode [Top]

Create an object by using a function that can contain the details of the object, and then return the 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 ', ' o ', [' Ajiao ', ' Tiantian ', ' Pangzi ']);

Each time the person function is called, a new object is created through the object o within the function, and then returned, which, in addition, has no other purpose than the internal object that exists in order to create the new object. In addition, the type of object created by the factory pattern cannot be judged.

1.1.2. Constructor pattern [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 of person by using the new operator
var person1 = new Person (' boy-a ', ', ', ' worker ');

var person2 = new Person (' girl-b ', ', ') ', ' Teacher ');

Person1.logname (); Boy-a

person2.logname ();//girl-a

Comparing Factory mode, you can find that there is no need to create intermediate objects, no return. In addition, an instance of a constructor can be identified as a specific type, which solves the problem of object recognition by checking the constructor property of the instance, or by using the instanceof operator to check whether the instance is created through a constructor.

Console.log (Person1.constructor = = person);//constructor is in the constructor prototype and points to the constructor, and the result is true

Console.log (person1 instanceof person);//through the instanceof operator, determine if Person1 is an instance of the constructor person but the constructor pattern also has its own problem, in fact, The LogName method is recreated once on each instance, and it should be noted that the method created by instantiating it is not equal, and the following code will get false:

Console.log (Person1.logname = = Person2.logname);//false We can move the method to the outside of the constructor (to become a global function) to solve the problem:

function LogName () {
  console.log (this.name);
}

function Logage () {
  console.log (this.age);
}

However, a global function created globally can only be invoked by an instance created by person, which is a bit of a misnomer; if there are many methods, you need to define each and the encapsulation.

1.1.3. prototype mode [Top]

Each function in JavaScript contains a pointer to the prototype property (most browsers can __proto__ access through internal properties), and the prototype property is an object that contains properties and methods that are 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 these things:

1. Defines a constructor Person,person function automatically obtains a prototype property, which defaults to only one constructor attribute pointing to the person;

2. Add three properties through Person.prototype, one as a method;

3. Create an instance of person and then invoke the LogName () method on the instance.

The calling procedure for the LogName () method is to be noted here:

1. Find the LogName () method on the Person1 instance and find no such method, and then trace back to the Person1 prototype

2. To find the Logame () method on a Person1 prototype, and then call the method based on a lookup procedure that prevents the instance from accessing the same name on the prototype by defining an attribute of the same name in the prototype on the instance, and it should be noted that Doing so does not delete the attribute with the same name on the prototype, just block instance access.

var person2 = new Person ();

Person2.name = ' Laocai '; if we no longer need the properties on the instance, we can delete them through the delete operator.

Delete person2.name; Use the for-in loop to enumerate all the properties that an instance can access, whether it exists in an instance or in a prototype:

For (i in Person1) {
  console.log (i);
}

At the same time, you can use the hasOwnProperty () method to determine whether an attribute exists on an instance or in a prototype, and returns true only if the attribute exists in the instance:

Console.log (Person1.hasownproperty (' name '));//true! hasOwnProperty, a prototype from object, is the only method in JavaScript that does not look up a prototype chain while processing an attribute. [via JavaScript Secret Garden] Alternatively, you can use the in operator and the hasOwnProperty () method to determine whether an attribute exists in the instance or in the prototype:

Console.log (' Friends ' in Person1) &&!person1.hasownproperty (' Friends '), first determine if Person1 can access the Friends property, if available, To determine whether this attribute exists in the instance (note the previous!), if it does not exist in the instance, the attribute exists in the prototype. As mentioned earlier, the prototype is also an object, so we can write the prototype with the object literal notation, which can be modified to include the code for the prototype:

Person.prototype = {

  name: ' Evansdiy ',
  friends: [' Ajiao ', ' Jianjian ', ' Pangzi '],
  logname:function () {
    Console.log (this.name);
  }

Because object literal syntax overrides the entire prototype prototype, the constructor property that was obtained by default when the constructor was created points to the object constructor:

Object literal after the prototype is overridden

Console.log (person1.constructor);//object However, the instanceof operator will still return the desired result:

Object literal after the prototype is overridden

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 you modify a prototype object after you create an object instance, 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, not a copy of the prototype, where the prototype is actually a search process, and any modifications made to the prototype object are reflected in all object instances, even if the prototype is modified after the instance is created. What happens if you rewrite a prototype object after you create an object instance?

function person () {};

var person1 = new Person1 ()//created instance refers to the original prototype

//rewrite prototype
person.prototype = {
  friends: [' Ajiao ', ' Jianjian ', ' Pangzi ']
}

var person2 = new Person ();//This instance references the newer

prototype Console.log (person2.friends);

Console.log (Person1.friends);

The above code will have undefined errors when executing to the last line, and if we use the for-in loop to enumerate the accessible properties in Person1, we find that there is nothing inside, but Person2 can access the Friends properties on the prototype. The rewrite prototype cuts off the connection between the existing prototype and all the object instances that were created earlier, and the prototype of the object instance that was created before is still in the old.

When Person1 is created, the prototype object has not been overridden, so the constructor in the prototype object or the default person ()

Console.log (Person1.constructor);//person ()

But Person2 's constructor point to object ()

Console.log (Person2.constructor);//object () Note that the prototype pattern ignores the process of passing parameters to the constructor, and all instances get the same property values. At the same time, there is a big problem in the prototype pattern, that is, the reference type value in the prototype object will be shared by all instances, and the modification of reference type value will be 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 ']

Modifying the Person1 reference type value friends means that the friends in Person2 will also change, in fact, the friends saved in the prototype is actually just a pointer to the friends value in the heap (the length of the pointer is fixed, stored on the stack), When an instance accesses a reference type value through a prototype, it is also accessed by a pointer instead of accessing the copy on the respective instance (such a copy does not exist).

1.1.4. Creating objects with constructors and prototype patterns [top]

Combined with the advantages of constructor function and prototype model, make up the shortcoming of each, make use of constructor function to pass initialization parameter, define instance attribute in it, use prototype to define common method and public property, this pattern 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 ', ') ';

var person2 = new Person (' Amy ', ' a ');

Person1.logname ();//' Evansdiy '

person1.friends.push (' Haixao ');

Console.log (person2.friends.length);//3

1.1.5. prototype dynamic mode [top]

The prototype dynamic pattern encapsulates all the information that is required into the constructor, using an if statement to determine whether a property exists in the prototype, and if it does not exist (at the time of the first call to the constructor), execute the prototype initialization code inside 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 ');//First Call constructor, at which time the prototype

var person2 = new Person (' Amy ', ' 21 ') is modified;//This time logname () Method already exists, no further modifications to the prototype

It is to be noted that the schema cannot write the prototype object using object literal syntax (this overrides the prototype object). If you rewrite the prototype, the prototype object that the first instance created through the constructor can access does not contain the stereotype object attribute 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 (' evansdiy ', ') ';

var person2 = new Person (' Amy ', ' a ');

Person2.logname ();//' Amy '

person1.logname ();//logname () method does not exist

What needs to be explained is that each pattern has its own application scene, does not matter the pros and cons.

The above analysis of the JavaScript in the creation of objects in a variety of patterns is small set to share all the content of everyone, hope to give you a reference, but also hope that we support the cloud habitat community.

Related Article

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.