JavaScript Object-Oriented Programming series (i)---creating objects

Source: Internet
Author: User
Tags hasownproperty

JavaScript is an object-based language, but it does not have the concept of class, so it is different from the actual object-oriented language, object-oriented is one of the difficulties in JavaScript. Now, in my understanding of the summary, easy to review later:

First, create the object

1. The simplest way to create a custom object is to create an instance of object and add properties and methods to it as follows:

var New Object ();    = "CC"= "White"function() {     alert (this. Name);  }

In recent years, object literals have become the preferred way to create objects, as follows:

var cat = {       "cc",       "white",             function() {               alert (  this. name);}       }    

Both of these methods can be used to create a single object, but these methods have obvious drawbacks: when creating multiple objects of the same type, there is a lot of duplication of code, so people are starting to use a variant of the factory pattern to solve this problem.

2. Factory mode Creation Object

Using the idea of Factory mode, a function is used to encapsulate the details of creating objects, and to provide a specific interface to implement the creation of objects, the above example can be written as follows:

function Createcat (name,color) {    varnew  Object ();     = name;     = color;     function () {             alert (this. Name);     }     return o;} var cat1 = Createcat ("CC", "white"); var

The function Createcat () can create a Cat object based on the name and suit of the cat received, we can call this function repeatedly, each call will return a two attributes and a method of the object, the object surface of the cat's name and suit, and can say the name of the cat.

The use of Factory mode to create objects can be a good solution to the above definition of a large number of duplicate code problems, but we can not really distinguish between the types of objects, we can only know that the object is created, but not recognized CAT1 and CAT2 are cat objects. To solve this problem, JavaScript proposes a constructor pattern.

3. Constructor mode

We know that there are many native constructors defined in ECMAScript, such as Array, Date, and we can use these native constructors to create objects of a particular type. In addition, JavaScript allows us to create custom constructors that define the properties and methods of object types, which are used to create objects of a certain class. We use the constructor pattern to rewrite the above example as follows:

function Cat (name,color) {       this. Name = name;         this. color = color;                 This function () {              alert (this. Name)       }}varnew Cat ("CC", "white" ); var New Cat ("VV", "Black");

We can use the cat () function instead of the createcat () function, and the cat () function has the following differences over the Createcat () function:

1> created objects that are not displayed;

2> attributes and methods are paid directly to the this object;

3> no return statement;

Also, we notice that the function name of the cat () function is capitalized in the first letter. According to the writing specification, the constructor is best to start with a capital letter, other functions start with lowercase letters, and of course, functions that start with lowercase letters can also be used as constructors to create objects. In fact, the constructor is essentially a function, but it is used to create objects.

When we use the cat () constructor to create an instance object, we must use the new operator, which is the following 4 steps to create an object in this way:

1> Creating a new object

2> in the constructor to point to the newly created object

3> execution of statements in constructors (that is, adding properties and methods to new objects)

4> returns this new object

In the example above, two different instances of the cat were created, each of which has a constructor (constructor) attribute that points to the constructor that created the instance, the Cat ()

Cat1.constructor = = Cat      //= =  truecat2.constructor = = Cat      //= =  true

The constructor property of an object is used to identify the object type. But JavaScript provides an operator instanceof to detect the type of object, the object created in the example above CAT1 and Cat2 is an instance of an object, and the instance of cat

instanceof Object   //=   trueinstanceof Cat        //+=   true instanceof Object   //=    trueinstanceof Cat        //+=   True

The above shows that, using the constructor pattern, we can identify the created object as a specific type. We also mentioned above that the constructor is actually a function, which differs from the normal function in that it is called differently. Any function, as long as it is called by the new operator, can be used as a constructor, and any function, not called by the new operator, is no different from a normal function call, as shown in the following example:

//use as a constructor functionvarCAT1 =NewCat ("CC", "white"); Cat1.say (); //= CC//As a normal function callCat ("VV", "block");//normal function Run, the This is the default window (ECMASCRIPT3)Window.say ();//= VV//called in another object scopevaro =NewObject (); Cat.call (0, "ss", "Yellow"); O.say (); //= Yellow

Above three ways to use, note the value of this

Although the constructor solves some of the problems above, it also has its own disadvantage, that is, every time an object is created, all its properties and methods are recreated, which will occupy a certain amount of memory, the two cat objects created in the above example CAT1 and Cat2, although their say () methods are the same, But it is not the same instance that occupies a different memory.

Cat1.say = = Cat2.say;    // =  false

But in practice, the methods in each object implement the same functionality, and there is absolutely no need to create multiple function instances, so we can solve this problem by defining the function outside the constructor.

 function   Cat (name,color) { this . Name = name;        color;   Sayname;}  function   Sayname () {alert ( this  .name);}  var  cat1 = new  Cat ("CC", "White" ); var  cat2 = new  Cat ("VV", "Black"); 

In the example above, we moved the say function outside so that CAT1 and CAT2 can share the Sayname function defined in the global, but there is a new problem, that is, the function defined in the global is only called by a certain class of objects, and the global scope is too chaotic, There is no encapsulation of objects, either. At this point, we can use the prototype mode to solve.

4. Prototype mode

In JavaScript, each function we create has a prototype (prototype) attribute, which is a pointer to an object, and all the properties and methods in the object are inherited by the instance object created by the constructor. That is, the prototype of each function is the prototype object of the instance object created by invoking the constructor. Let's look at an example

functionPerson () {}person.prototype.name= "CC"; Person.prototype.age= "2"; Person.prototype.job= "Software Engineer"; Person.prototype.sayName=function() {alert ( This. name);}varPerson1 =NewPerson ();p erson1.sayname (); //= "CC"varPerson2 =NewPerson ();p erson2.sayname (); //= "CC"Person1.sayname= = Person2.sayname;//= True

We place the attributes of person in their prototype object, and the instance objects Person1 and person2 that they create contain an intrinsic property that points to the person's prototype function Person.prototype. We use the diagram to show (lazy here, directly on the elevation chart):

This shows the relationship between the person constructor, the prototype property of the person, and the two instance objects of the man. Where the person has a prototype attribute pointing to its prototype object, and the person's prototype object has a constructor function pointing to person. The internal properties of its two instance objects [[Prototype]] (which are not currently accessed in standard ways) point to Person.prototype. As we can see, the instance object created is not directly related to the constructor function.

In the above example, although both Person1 and Person2 do not have properties and methods, they can call the Sayname () method. Whenever a property of an object is read, a search is performed, first searching the instance object itself, and then continuing to search for the prototype object that the object points to if it is not found, returning if there is one, and returning undefined if none.

the above object instance can access the properties and methods in the prototype, but cannot override the values in the prototype. If we override a property in the instance with the same name in the prototype, the property is created in the instance and the same name property is masked in the prototype, but the properties in the prototype are not modified. is as follows:

functionPerson () {}person.prototype.name= "CC"; Person.prototype.age= "2"; Person.prototype.job= "Software Engineer"; Person.prototype.sayName=function() {alert ( This. name);}varPerson1 =NewPerson ();varPerson2 =NewPerson ();p erson1.name= "VV";p Erson1.name; //= VVPerson2.name;//= CCPerson.prototype.name;//= CC

Each time you add properties and methods to the prototype in the previous instance, you enter Person.prototype. So we can use the object literal to rewrite the prototype object as follows:

function= {       "cc",       2,       "Software Engineer",        function() {                alert (this. Name);       }}

The above code defines a person.prototype that is almost identical to the prototype object defined above, but with an exception, using object literals to redefine the prototype object (equivalent to redefining an object), whose constructor attribute does not point to the person, but to the object constructor. You can also return the correct results using the instanceof operator, but you cannot determine the type of the object using the constructor property.

var New  instanceof Object;   // = =  trueinstanceof person;  // = =   truenewperson.constructor = = Object;  // = = Truenewperson.constructor = = person;  // = False

If we need the constructor property, you can set its value manually.

Note: We can add the properties and methods of the prototype at any time, and can react to it immediately in the instance, but we have to be careful to rewrite the location of the prototype object. Calling the constructor creates an object that adds a pointer to the prototype, and if we rewrite the object's prototype function, it cuts off the relationship between the created instance and the constructor.

functionPerson1 () {}person1.prototype.name= "CC"; Person1.prototype.say=function() {alert ( This. name);}varFriend1 =NewPerson1 (); Friend.say (); //= CCfunctionPerson () {}varFriend =NewPerson (); Person.prototype={constructor:person, Name:"CC", Age:2, Job:"Software Engineer", Sayname:function() {alert ( This. Name);  }}friend.sayname (); //= Error

Disadvantages of prototype mode:

1> cannot pass initialization parameters through constructors

2> instance sharing for reference types

Let's look at an example:

functionPerson () {}person.prototype={constructor:person, Name:"CC", Age:2, Job:"Software Engineer", friends: ["VV", "DD"], Sayname:function() {alert ( This. Name); }  }varPerson1 =NewPerson ();varPerson2 =NewPerson ();p Erson1.friends.push ("AA");p erson1.friends; //= Vv,dd,aaPerson2.friends;//= Vv,dd,aaPerson1.friends = = Person2.friends;//= True

The above code, when we modify the Person1.friends, the corresponding person2.friends will also change, because they point to the same array. In practice, however, we usually want the instance to have its own independent property, so we propose a method of combining the constructor pattern and the prototype pattern , which is the most widely used and most agreeable method of creating a custom type.

functionCat (name,color) { This. Name =name;  This. color =color;  This. firends = ["AA", "BB"];} Cat.prototype={constructor:cat, sayname:function() {alert ( This. Name); }}varCAT1 =NewCat ("CC", "white");varCAT2 =NewCat ("VV", "block"); Cat1.firends.push ("DD"); cat1.firends; //= Aa,bb,ddCat2.firends;//= Aa,bbCat1.firends = = Cat2.firends;//= FalseCat1.sayname = = Cat2.sayname;//= True

From the above example, we can put the properties that we want the instance object to have in the constructor, put the attributes that we want the strength object to share into the prototype, effectively solve the problem.

5. Several methods of detecting object type

1> isprototypeof () method

Currently we cannot access [[prototype]] in all implementations, but we can use the isprototypeof () method to determine whether this relationship exists between objects if the [[prototype]] property of an object points to the call isprototypeof ( ) Method object, returns True, otherwise false, as follows:

Person.prototype.isPrototypeOf (Person1);   // = True Person.prototype.isPrototyoeOf (Person2);   // = True

Above, we test Person1 and person2 with the person's prototype object, both of which return true.

2> object.getprototypeof () method (ECMAScript5 new definition)

This method returns the value of [[prototype]], such as:

Object.getprototypeof (person1) = = Person.prototype;  // = =  trueobject.getprototypeof (person1). Name;  // =  "CC"

3> hasOwnProperty () method

This method is used to detect whether a property exists in an instance, rather than in a prototype, such as:

Person1.name;  // ~ = cc   from prototype person1.hasownproperty ("name");  // = =   false= "VV";  // = =  from the instance person1.hasownproperty ("name");  // =  true

In the example above, when the name property of Person1 comes from the prototype, hasOwnProperty () returns false and returns true after the Name property is overridden for Person1.

4> in operator

There are two ways to use the In operator: use it alone or in a for-in loop.

When used alone, the in operator can be used to detect whether a given property can be accessed by an object, whether the attribute exists in an instance or in a prototype

Person1.name;   // = =  cc  //=> from prototype in Person1;   // = =   true= "VV";  // = = from the instance inch // =  true

As can be seen in the example above, if the object's properties are derived from the prototype or from the instance, it returns true whenever it is accessed by the Person1 object.

In the for-in loop, all enumerable properties that can be accessed by the object are returned, including the attributes in the instance, as well as the properties in the prototype. Instance properties that mask non-enumerable properties in the prototype are also returned in the for-in loop because all developer-defined properties are enumerable (IE8 and earlier versions will not be returned).

JavaScript Object-Oriented Programming series (i)---creating objects

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.