An in depth analysis of JavaScript object oriented and prototype functions

  • 2020-12-16 05:49:34
  • OfStack

Object is a very important stem in javascript, whether you can thoroughly understand it is directly related to your basic understanding of the entire javascript system, to put it bluntly, javascript is a group of objects in stir. (beep beep! .

Here are some common object creation patterns

Create using the new keyword

The most basic way to create objects is nothing more than what most other languages say: no objects, you new1 ah!


var gf = new Object(); gf.name = "tangwei"; gf.bar = "c++"; gf.sayWhat = function() { console.log(this.name + "said:love you forever"); }

Create with literals

This seems fine, but geek is a quiet language that likes the complexity and the way low defines variables. As a scripting language, it should have the same style as its brothers. Hence the definition of object literal:


var gf = { name : "tangwei", bar : "c++", sayWhat : function() { console.log(this.name + "said:love you forever"); } }

The factory pattern

This is actually the most common way we define objects in practice, but I'm going to have a lot of objects with similar properties (it's exciting to think about...). What to do? If the definition of 1, will generate a lot of code, why not build a factory, mass production of our object, so, javascript world's first inflatable doll... No, the factory model was born!


function createGf(name, bar) { var o = new Object(); o.name = name; o.bar = bar; o.sayWhat = function() { alert(this.name + "said:love you forever"); } return o; } var gf1 = createGf("bingbing","d"); var gf2 = createGf("mimi","a");

The constructor

The factory pattern solves the problem of creating multiple similar objects, but then again, these objects are all rounded out by Object. How do you distinguish their specific object types? At this point we need to switch to another mode, constructor mode:


function Gf(name,bar){ this.name = name; this.bar = bar; this.sayWhat = function(){ alert(this.name + "said:love you forever"); } } var gf1 = new Gf("vivian","f"); var gf2 = new Gf("vivian2","f");

Instead of createGf in the example above, we use a constructor that starts with a capital letter. Note that the constructor is capitalized by convention. Here we create a new object, assign the constructor scope to the new object, and call the method in the constructor.

The above approach seems fine, but we can see that the sayWhat method in the constructor invoked in both instances is not the same as one instance of Function:


console.log(gf1.sayWhat == gf2.sayWhat); //false

Calling the same method but declaring different instances is a waste of resources. We can optimize 1 to put the sayWhat function outside the constructor and declare:


function Gf(name,bar){ this.name = name; this.bar = bar; this.sayWhat = sayWhat } function sayWhat(){ alert(this.name + "said:love you forever"); }

This solves the problem of multiple instances defining the same method instance multiple times, but a new problem arises. sayWhat is a globally scoped method, but this method cannot be called directly, which is a bit contradictory. How to define an object with definite encapsulation more elegantly? Let's look at the javascript prototype object pattern in 1.

Prototype object pattern

Understanding prototype objects

When we create a function, the function will have an prototype attribute that points to the prototype object of the function created through the constructor. In layman's terms, prototype objects are objects in memory that provide shared properties and methods for other objects.

In the stereotype schema, instead of defining instance properties in the constructor, attribute information can be given directly to the stereotype object:


function Gf(){ Gf.prototype.name = "vivian"; Gf.prototype.bar = "c++"; Gf.prototype.sayWhat = function(){ alert(this.name + "said:love you forever"); } } var gf1 = new Gf(); gf1.sayWhat(); var gf2 = new Gf();

Unlike the constructor, the properties and methods of the new object are shared by all instances; in other words, gf1 and gf2 access the same properties and methods. In addition to the properties we've given the prototype object, there are a few built-in properties. All prototype objects have an constructor property, which is a pointer to a function containing the prototype property (do you want to wrap it again!). . Through the figure 1, we can clearly understand the flow of this winding:

All objects have a prototype object (prototype), a prototype object in one constructor containing prototype attribute function, examples of Gf gf1 and gf2 contains an internal attribute points to the prototype object (characterized by private property in firefox browser proto), when we access attributes of an object, first will ask instance objects have this property, if there is no continued to search a prototype object.

Using prototype objects

In the previous example, we noticed that we need to add Gf.prototype to each of the prototype objects when adding attributes to them. This is a very repetitive task. In the above object creation mode, we know that we can create 1 object by literal form, here we can also improve 1:


function Gf(){} Gf.prototype = { name : "vivian", bar : "c++", sayWhat : function(){ alert(this.name + "said:love you forever"); } }

There is one place need to pay special attention to, constructor properties to objects no longer Gf, because each define a function, can at the same time to create a prototype object, that object will automatically get a new constructor attributes, the place we use Gf. prototype essentially fu wrote the original prototype object, therefore constructor constructor attributes into a new object, no longer pointing Gf, but Object:


var gf1 = new Gf(); console.log(gf1.constructor == Gf);//false console.log(gf1.constructor == Object)//true

1 Normally, this subtle change will not affect us, but if you have specific requirements for constructor, we can also explicitly specify the constructor attribute for ES100en.prototype:


Gf.prototype = { constructor : Gf, name : "vivian", bar : "c++", sayWhat : function() { alert(this.name + "said:love you forever"); } } var gf1 = new Gf(); console.log(gf1.constructor == Gf);//true

Through the preliminary understanding of the prototype object pattern, we found that all the instance objects share the same properties, this is the basic characteristics of prototype patterns, but often it is the "double-edged sword" for developers, in the actual development, we hope the case should be have their own properties, which is rarely used alone in the actual development the main reason for the prototype model.

Constructors and prototypes combine patterns

In real development, we can use constructors to define properties of objects and stereotypes to define shared properties and methods, so that we can pass different parameters to create different objects and have shared methods and properties.


var gf = { name : "tangwei", bar : "c++", sayWhat : function() { console.log(this.name + "said:love you forever"); } }
0

In this example, we define the respective property values of the object in the constructor, and the constructor property and sayWhat function in the prototype object, so that there is no effect between the gf1 and gf2 properties. This pattern is also the most commonly used way of defining objects in practical development, including the default mode adopted by many JS libraries (bootstrap, etc.).

The above is the JavaScript object oriented and prototype function introduced by this site. I hope it will be helpful to you.


Related articles: