Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using the JavaScript revealing prototype pattern, how can I namespace functions contained within prototypes?

I'm using the Revealing Prototype Pattern and have 2 different prototypes that I'm putting into the same JavaScript file. These links are to articles I found which relate to this. http://bit.ly/U83hdg, http://bit.ly/VmJ71h.

I was under the impression that these would operate like atomic classes, where functions associated with one would be unaware of functions in the other.

For instance, both of these prototypes have an "init" and a "set" function. The behavior I'm seeing in the browser is that the last version of "init" gets executed, even when the code references the first prototype name.

This is generic stripped-down code from my two prototypes.

var operationA = function (control, settings) {
   this.control = control;
   this.settings = settings;
};

operationA.prototype = function () {
   init = function () {
      // do something
      return this;
   }
   set = function () {
      // do something
      return this;
   };

   return {
      init: init,
      set: set
   };
}

var operationB = function (control, settings) {
   this.control = control;
   this.settings = settings;
};

operationB.prototype = function () {
   init = function () {
      // do something
      return this;
   }
   set = function () {
      // do something
      return this;
   };

   return {
      init: init,
      set: set
   };
}

This is how I'm instantiating the first object.

var objectASettings = {
   property1: 48,
   property2: 37
};
var objectA = new operationA('#mySelector', objectASettings);
objectA.init().set();

When the above runs, the init and set functions from the prototype for operationB are being executed, instead of executing the init and set functions from the prototype for operationA.

I assumed these prototypes basically namespaced their contained functions. Am I required to create unique public function names for operationA and operationB (like initA , setA, initB, setB)?

Is there a way to self-contain and/or namespace these public functions, so I can expose the same operation names of init and set on 2 different prototypes in the same file?

Thanks for your help.

like image 549
Ken Palmer Avatar asked Jan 28 '26 04:01

Ken Palmer


2 Answers

A couple of things to get it working:

  1. Add var before the first member in the prototype function.
  2. Separate each member with a comma (you can certainly put var in front of each member but I like to keep it clean...personal preference though).
  3. The function assigned to the prototype must be self-invoked for the pattern to work properly.

Here's an example that should work for you:

<html>
<head>
   <script>
        var operationA = function (control, settings) {
           this.control = control;
           this.settings = settings;
        };

        operationA.prototype = function () {
           var init = function () {
              // do something
              return this;
           },
           set = function () {
              alert('set A');
              return this;
           };

           return {
              init: init,
              set: set
           };
        }();

        var operationB = function (control, settings) {
           this.control = control;
           this.settings = settings;
        };

        operationB.prototype = function () {
           var init = function () {
              // do something
              return this;
           }, 
           set = function () {
              alert('set B');
              return this;
           };

           return {
              init: init,
              set: set
           };
        }();

        window.onload = function() {
            var objectASettings = {
               property1: 48,
               property2: 37
            };
            var objectBSettings = {
               property1: 50,
               property2: 50
            };
            var objectA = new operationA('#mySelector', objectASettings);
            objectA.init().set();

            var objectB = new operationB('#foo', objectBSettings)
            objectB.init().set();
        }
   </script>
</head>

like image 181
Dan Wahlin Avatar answered Jan 29 '26 17:01

Dan Wahlin


You're omitting the var keyword when defining init and set so they're both assigned to the global object.

like image 25
AlienWebguy Avatar answered Jan 29 '26 17:01

AlienWebguy



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!