Prototypes and libraries

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Andrew Poulos

    Prototypes and libraries

    If I'm building a javascript library (an object) like so:

    myLib = new Object():
    myLib.myFunctio n = function() {
    // blah
    }

    What happens if I want to add a prototype to myFunction? I'm converting
    some code from this form:

    MyFunction = function(){
    // blah
    }
    MyFunction.prot otype.myMethod = function() {
    // blah
    }

    and I'm wondering what the implications are.


    Andrew Poulos
  • Michael Winter

    #2
    Re: Prototypes and libraries

    On Sat, 01 Jan 2005 15:47:34 +1100, Andrew Poulos <ap_prog@hotmai l.com>
    wrote:
    [color=blue]
    > If I'm building a javascript library (an object) like so:[/color]

    I assume this is related to your post last Wednesday regarding name
    clashes.
    [color=blue]
    > myLib = new Object():
    > myLib.myFunctio n = function() {
    > // blah
    > }[/color]

    I tend to find that:

    var myLib = (function() {
    return {
    myFunction : function() {
    },
    myOtherFunction : function() {
    }
    };
    })();

    is better. This allows to use "global" variables, but keeping them within
    the object:

    var myLib = (function() {
    var myPrivate = 0;

    return {
    myMethod : function() {
    alert(++myPriva te);
    }
    };
    })();

    myLib.myMethod( ); // alert 1
    myLib.myMethod( ); // 2
    myLib.myMethod( ); // 3

    The initial return (assigned to myLib) could be anything. I used an object
    literal above as that's what you'd probably use when creating a
    library-like object, but it could also be function (a constructor
    function, for example) or anything else that might be more useful.

    If you do manage to use this form exclusively, you'd only add one global
    variable. If that clashed, client software could just use a different
    name, even if you want to call one of your own methods:

    var myLib = (function() {
    return {
    myMethod1 : function() {
    alert('myMethod 1 called');
    this.myMethod2( );
    },
    myMethod2 : function() {
    alert('myMethod 2 called');
    }
    };
    })();

    myLib.myMethod1 (); // myMethod1 called
    // myMethod2 called

    As long as myMethod1 is called through the library object (whatever it's
    called), the this operator will refer to the library and myMethod2 would
    be called as expected.
    [color=blue]
    > What happens if I want to add a prototype to myFunction?[/color]

    Adding a prototype would only have any meaningful effect if myFunction was
    a constructor.
    [color=blue]
    > I'm converting some code from this form:
    >
    > MyFunction = function(){
    > // blah
    > }
    > MyFunction.prot otype.myMethod = function() {
    > // blah
    > }[/color]

    From that form into which form?
    [color=blue]
    > and I'm wondering what the implications are.[/color]

    Your question seems exceedingly vague. Could you post an example of the
    code before and after your changes. Preferably something non-trivial.

    Mike

    --
    Michael Winter
    Replace ".invalid" with ".uk" to reply by e-mail.

    Comment

    • Andrew Poulos

      #3
      Re: Prototypes and libraries

      Michael Winter wrote:[color=blue]
      > On Sat, 01 Jan 2005 15:47:34 +1100, Andrew Poulos <ap_prog@hotmai l.com>
      > wrote:
      >[color=green]
      >> If I'm building a javascript library (an object) like so:[/color]
      >
      >
      > I assume this is related to your post last Wednesday regarding name
      > clashes.
      >[color=green]
      >> myLib = new Object():
      >> myLib.myFunctio n = function() {
      >> // blah
      >> }[/color]
      >
      >
      > I tend to find that:
      >
      > var myLib = (function() {
      > return {
      > myFunction : function() {
      > },
      > myOtherFunction : function() {
      > }
      > };
      > })();
      >
      > is better. This allows to use "global" variables, but keeping them
      > within the object:
      >
      > var myLib = (function() {
      > var myPrivate = 0;
      >
      > return {
      > myMethod : function() {
      > alert(++myPriva te);
      > }
      > };
      > })();
      >
      > myLib.myMethod( ); // alert 1
      > myLib.myMethod( ); // 2
      > myLib.myMethod( ); // 3
      >
      > The initial return (assigned to myLib) could be anything. I used an
      > object literal above as that's what you'd probably use when creating a
      > library-like object, but it could also be function (a constructor
      > function, for example) or anything else that might be more useful.
      >
      > If you do manage to use this form exclusively, you'd only add one
      > global variable. If that clashed, client software could just use a
      > different name, even if you want to call one of your own methods:
      >
      > var myLib = (function() {
      > return {
      > myMethod1 : function() {
      > alert('myMethod 1 called');
      > this.myMethod2( );
      > },
      > myMethod2 : function() {
      > alert('myMethod 2 called');
      > }
      > };
      > })();
      >
      > myLib.myMethod1 (); // myMethod1 called
      > // myMethod2 called
      >
      > As long as myMethod1 is called through the library object (whatever
      > it's called), the this operator will refer to the library and myMethod2
      > would be called as expected.
      >[color=green]
      >> What happens if I want to add a prototype to myFunction?[/color]
      >
      >
      > Adding a prototype would only have any meaningful effect if myFunction
      > was a constructor.
      >[color=green]
      >> I'm converting some code from this form:
      >>
      >> MyFunction = function(){
      >> // blah
      >> }
      >> MyFunction.prot otype.myMethod = function() {
      >> // blah
      >> }[/color]
      >
      >
      > From that form into which form?
      >[color=green]
      >> and I'm wondering what the implications are.[/color]
      >
      >
      > Your question seems exceedingly vague. Could you post an example of the
      > code before and after your changes. Preferably something non-trivial.
      >
      > Mike[/color]

      Thanks for your help.

      Here's some sample code that I want to convert to a library type
      approach. (Note the object "Obj" has been setup earlier). I'm getting
      caught on the idea behind how blah.onlick = this.playSound; would
      convert. There are other bugs in the code as it's a work in progress.

      function MySound(sndUrl, num) {
      this.sndURL = sndUrl;
      var t = sndUrl.toLowerC ase();
      var s = t.lastIndexOf(" .");
      t = t.substr(s);
      switch(t) {
      case ".aif":
      this.datatype = "audio/x-aiff";
      break;
      case ".mid":
      this.datatype = "audio/mid";
      break;
      case ".mp3":
      this.datatype = "audio/mpeg";
      break;
      case ".wav":
      this.datatype = "audio/x-wav";
      break;
      case ".wma":
      this.datatype = "applicatio n/x-mplayer2";
      break;
      }
      this.load();
      document.getEle mentById("play" +num).onclick = this.playSound;
      document.getEle mentById("stop" +num).onclick = this.stopSound;
      }

      MySound.prototy pe.load = function() {
      if (!document.getE lementById("div Audio")) {
      Obj.mediaDiv = document.create Element("div");
      Obj.mediaDiv.se tAttribute("id" , "divAudio") ;
      Obj.mediaDiv.st yle.position = "absolute";
      Obj.mediaDiv.st yle.visibility = "hidden";
      document.body.a ppendChild(Obj. mediaDiv);
      } else {
      Obj.mediaDiv = document.getEle mentById("divAu dio");
      }
      if (Obj.isCompat) {
      var mediaObj = document.create Element("object ");
      mphAddParam(med iaObj,"FileName ",this.sndU RL);
      mphAddParam(med iaObj,"AutoStar t","false");
      Obj.mediaDiv.ap pendChild(media Obj);

      mediaObj.id = "objmedia" +
      (Obj.mediaDiv.c hildNodes.lengt h-1).toString();
      mediaObj.classi d = "CLSID:22d6 f312-b0f6-11d0-94ab-0080c74c7e95";
      mediaObj.codeBa se =
      "http://activex.microso ft.com/activex/controls/mplayer/en/nsmp2inf.cab#Ve rsion=6,4,5,715 ";
      }
      }

      MySound.prototy pe.playSound = function() {
      // get the sound number
      var tmp = parseInt( this.id.replace (/\D/gi,' '),10 );
      var objID = "objmedia"+ tmp;

      if (Obj.isCompat) {
      document.getEle mentById(objID) .Play();
      } else {
      var c = document.getEle mentById(objID) ;
      if (c) Obj.mediaDiv.re moveChild(c);

      var mediaObj = document.create Element("object ");
      mediaObj.id = "objmedia" + tmp.toString();
      mediaObj.setAtt ribute("type",m phMain["snd"+tmp].datatype);
      mediaObj.setAtt ribute("data",m phMain["snd"+tmp].sndURL);

      mphAddParam(med iaObj,"AutoStar t","true");

      mphObj.mediaDiv .appendChild(me diaObj);
      }
      }

      MySound.prototy pe.stopSound = function() {
      var tmp = parseInt( this.id.replace (/\D/gi,' '),10 );
      var objID = "objmedia"+ tmp;

      if (Obj.isIE) {
      document.getEle mentById(objID) .Stop();
      } else {
      var c = document.getEle mentById(objID) ;
      if (c) Obj.mediaDiv.re moveChild(c);
      }
      }


      Andrew Poulos

      Comment

      • Michael Winter

        #4
        Re: Prototypes and libraries

        On Sun, 02 Jan 2005 11:48:05 +1100, Andrew Poulos <ap_prog@hotmai l.com>
        wrote:

        [snip]
        [color=blue]
        > Here's some sample code that I want to convert to a library type
        > approach.[/color]

        I don't see any need to do anything to that code.

        [snip]

        Mike

        --
        Michael Winter
        Replace ".invalid" with ".uk" to reply by e-mail.

        Comment

        • Andrew Poulos

          #5
          Re: Prototypes and libraries

          Michael Winter wrote:[color=blue]
          > On Sun, 02 Jan 2005 11:48:05 +1100, Andrew Poulos <ap_prog@hotmai l.com>
          > wrote:
          >
          > [snip]
          >[color=green]
          >> Here's some sample code that I want to convert to a library type
          >> approach.[/color]
          >
          >
          > I don't see any need to do anything to that code.
          >
          > [snip][/color]

          That means I don't yet understand when a library type approach is
          appropriate.

          Thanks for the help.

          Andrew Poulos

          Comment

          • Andrew Poulos

            #6
            Re: Prototypes and libraries

            [snip]
            [color=blue]
            > var myLib = (function() {
            > return {
            > myMethod1 : function() {
            > alert('myMethod 1 called');
            > this.myMethod2( );
            > },
            > myMethod2 : function() {
            > alert('myMethod 2 called');
            > }
            > };
            > })();
            >
            > myLib.myMethod1 (); // myMethod1 called
            > // myMethod2 called[/color]

            If I did choose to use the approach you've outlines above, is there a
            way to add more methods to the library at some later stage (in the way a
            constructor function can have prototypes added)?


            Andrew Poulos

            Comment

            • Michael Winter

              #7
              Re: Prototypes and libraries

              On Mon, 03 Jan 2005 08:59:56 +1100, Andrew Poulos <ap_prog@hotmai l.com>
              wrote:

              [snip]
              [color=blue]
              > That means I don't yet understand when a library type approach is
              > appropriate.[/color]

              The pattern I showed is mainly used for encapsulation. For example, when
              you want to separate a public interface (a constructor or factory
              function, or an object) from supporting code that client software
              shouldn't have (or need) access to.

              Mike

              --
              Michael Winter
              Replace ".invalid" with ".uk" to reply by e-mail.

              Comment

              • Michael Winter

                #8
                Re: Prototypes and libraries

                On Mon, 03 Jan 2005 10:48:11 +1100, Andrew Poulos <ap_prog@hotmai l.com>
                wrote:
                [color=blue]
                > [...] is there a way to add more methods to the library at some later
                > stage (in the way a constructor function can have prototypes added)?[/color]

                If you're modifying the public interface, then yes, it's easy.

                From outside the "library":

                myLib.newMethod = function() {
                /* ... */
                };

                If you're modifying the interface from inside, then it depends what's
                modifying it.

                Interface code:

                var myLib = (function() {
                return {
                myMethod : function() {
                this.newMethod = function() {
                /* ... */
                };
                }
                };
                })();

                Private code:

                var myLib = (function() {
                var _i;

                function myFunction() {
                _i.newMethod = function() {
                /* ... */
                };
                }

                return (_i = {
                /* Interface */
                });
                })();


                If you're attempting to modify private code within the "library", then
                it's fairly difficult to do externally - you'd have to provide access to
                it which would negate the point of hiding the code in the first place.

                Hope that helps,
                Mike

                --
                Michael Winter
                Replace ".invalid" with ".uk" to reply by e-mail.

                Comment

                • Robert

                  #9
                  Re: Prototypes and libraries

                  In article
                  <41d86ed3$0$180 11$5a62ac22@per-qv1-newsreader-01.iinet.net.au >,
                  Andrew Poulos <ap_prog@hotmai l.com> wrote:
                  [color=blue]
                  > That means I don't yet understand when a library type approach is
                  > appropriate.[/color]

                  What is the library approach?

                  Robert

                  Comment

                  Working...