combining the constructor pattern with the prototype pattern
A common way to create custom types is to combine the constructor pattern with the prototype pattern. The constructor pattern is used to define instance properties, and the prototype schema is used to define methods and shared properties. As a result, each instance will have its own copy of the instance properties, but at the same time share a reference to the method, saving memory for a significant amount. In addition, this blending pattern also supports passing parameters to the constructor, which is the length of the two modes.
<script>functionPerson (name, age, job) { This. Name =name; This. Age =Age ; This. Job =job; This. Friends = ["Shelby", "Sylvia"]; } Person.prototype={Constructor:person, showfriends:function () { varMessage = This. Name + ":"; This. Friends.foreach (function(V, I, array) {message+= " " +v; }); alert (message); } } varP1 =NewPerson ("Gck", "Senior software Engineer"); P1.friends.push ("Carol"); P1.showfriends (); varP2 =NewPerson ("Gck", "Senior software Engineer"); P2.showfriends (); </script>
In this example, the instance properties are defined in the constructor, and the properties constructor and Method Sayname () shared by all instances are defined in the prototype. modifying Person1.friends (Adding a new string to it) does not affect person2.friends, because they refer to different arrays respectively. This pattern of constructors and prototypes is a method of creating custom types that are used extensively and with high degree of recognition in ECMAScript. It can be said that this is a default pattern for defining reference types.
Dynamic Prototyping Mode
functionPerson (name, age, job) {//Properties This. Name =name; This. Age =Age ; This. Job =job; //Method if(typeof This. sayname! = "function") {Person.prototype.sayName=function() {alert ( This. Name); }; } } varFriend =NewPerson ("Nicholas", "Software Engineer"); Friend.sayname ();
Note The bold part of the constructor code. This is only added to the prototype if the Sayname () method does not exist. This code will only be executed when the constructor is first called. Since then, the prototype has been initialized and there is no need to make any changes. Keep in mind, however, that the modifications made to the prototype here can be immediately reflected in all instances. So this approach is really perfect. Where the If statement checks for any properties or methods that should exist after initialization--you do not have to examine each property and each method with a large heap of if statements, just check one of them. For objects created with this pattern, you can also use the instanceof operator to determine its type.
Note: You cannot use object literals to rewrite prototypes when using dynamic prototype mode. As explained earlier, if you rewrite the prototype with the instance already created, the connection between the existing instance and the new prototype will be severed.
Parasitic constructor Mode
functionPerson (name, age, job) {varo =NewObject (); O.name=name; O.age=Age ; O.job=job; O.sayname=function() {alert ( This. Name); }; returno; } varFriend =NewPerson ("Nicholas", "Software Engineer");
Friend.sayname ();//"Nicholas"
In this example, the person function creates a new object, initializes the object with the appropriate properties and methods, and then returns the object. In addition to using the new operator and using the wrapper function called the constructor, this pattern is exactly the same as the factory pattern. The constructor returns a new object instance by default, without returning a value. Instead, you can override the value that is returned when the constructor is called by adding a return statement at the end of the constructor function. This pattern can be used to create constructors for objects in special cases. Suppose we want to create a special array with extra methods. This pattern can be used because the Array constructor cannot be modified directly.
<script>functionSpecialarray () {//Create an array varValues =NewArray (); //Add Valuevalues.push.apply (values, arguments); //Add MethodValues.topipedstring =function() { return This. Join ("|"); }; //returns an array returnvalues; } varcolors =NewSpecialarray ("Red", "Blue", "green"); Alert (colors.topipedstring ()); //"Red|blue|green"</script>
In this example, we created a constructor called Specialarray. Inside this function, an array is created first, and then the Push () method (all parameters received by the constructor) initializes the value of the array. A topipedstring () method is then added to the array instance, which returns the array values separated by a vertical bar. , the array is returned in the form of a function value. We then called the Specialarray constructor, passed in the value used to initialize the array, and then called the Topipedstring () method. As for the parasitic constructor pattern, one thing to note: First, there is no relationship between the returned object and the constructor or the stereotype property of the constructor, that is, the object returned by the constructor is not the same as the object created outside the constructor. To do this, you cannot rely on the instanceof operator to determine the object type. Because of these problems, we recommend that you do not use this mode if you can use other modes.
Secure Constructor Mode
<script> function person (name, age, Job) { // Create an object to return var o = new Object (); // Here you can define private variables and functions // Add method O.sayname = function () {alert (name); }; // return object return o; } </script>
Note that in objects created in this mode, there is no other way to access the value of name in addition to using the Sayname () method. You can use the secure person constructor as below.
var friend = person ("Nicholas", "Software Engineer"); Friend.sayname (); "Nicholas" This way, a variable friend holds a secure object, and in addition to calling the Sayname () method, there is no other way to access its data members. Even if other code adds methods or data members to the object, there is no way to access the raw data passed into the constructor. The secure constructor pattern provides this security, making it ideal for some secure execution environments.
Note: Similar to the parasitic constructor pattern, objects created with the secure constructor pattern have little to do with constructors, so the instanceof operator does not make sense for such objects.
Several patterns created by the JavaScript review object