By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,627 Members | 1,870 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,627 IT Pros & Developers. It's quick & easy.

Prototypes and libraries

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

myLib = new Object():
myLib.myFunction = 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.prototype.myMethod = function() {
// blah
}

and I'm wondering what the implications are.
Andrew Poulos
Jul 23 '05 #1
Share this Question
Share on Google+
8 Replies


P: n/a
On Sat, 01 Jan 2005 15:47:34 +1100, Andrew Poulos <ap*****@hotmail.com>
wrote:
If I'm building a javascript library (an object) like so:
I assume this is related to your post last Wednesday regarding name
clashes.
myLib = new Object():
myLib.myFunction = function() {
// blah
}
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(++myPrivate);
}
};
})();

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('myMethod1 called');
this.myMethod2();
},
myMethod2 : function() {
alert('myMethod2 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.
What happens if I want to add a prototype to myFunction?
Adding a prototype would only have any meaningful effect if myFunction was
a constructor.
I'm converting some code from this form:

MyFunction = function(){
// blah
}
MyFunction.prototype.myMethod = function() {
// blah
}
From that form into which form?
and I'm wondering what the implications are.


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.
Jul 23 '05 #2

P: n/a
Michael Winter wrote:
On Sat, 01 Jan 2005 15:47:34 +1100, Andrew Poulos <ap*****@hotmail.com>
wrote:
If I'm building a javascript library (an object) like so:

I assume this is related to your post last Wednesday regarding name
clashes.
myLib = new Object():
myLib.myFunction = function() {
// blah
}

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(++myPrivate);
}
};
})();

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('myMethod1 called');
this.myMethod2();
},
myMethod2 : function() {
alert('myMethod2 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.
What happens if I want to add a prototype to myFunction?

Adding a prototype would only have any meaningful effect if myFunction
was a constructor.
I'm converting some code from this form:

MyFunction = function(){
// blah
}
MyFunction.prototype.myMethod = function() {
// blah
}

From that form into which form?
and I'm wondering what the implications are.

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

Mike


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.toLowerCase();
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 = "application/x-mplayer2";
break;
}
this.load();
document.getElementById("play"+num).onclick = this.playSound;
document.getElementById("stop"+num).onclick = this.stopSound;
}

MySound.prototype.load = function() {
if (!document.getElementById("divAudio")) {
Obj.mediaDiv = document.createElement("div");
Obj.mediaDiv.setAttribute("id", "divAudio");
Obj.mediaDiv.style.position = "absolute";
Obj.mediaDiv.style.visibility = "hidden";
document.body.appendChild(Obj.mediaDiv);
} else {
Obj.mediaDiv = document.getElementById("divAudio");
}
if (Obj.isCompat) {
var mediaObj = document.createElement("object");
mphAddParam(mediaObj,"FileName",this.sndURL);
mphAddParam(mediaObj,"AutoStart","false");
Obj.mediaDiv.appendChild(mediaObj);

mediaObj.id = "objmedia" +
(Obj.mediaDiv.childNodes.length-1).toString();
mediaObj.classid = "CLSID:22d6f312-b0f6-11d0-94ab-0080c74c7e95";
mediaObj.codeBase =
"http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=6,4,5,715";
}
}

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

if (Obj.isCompat) {
document.getElementById(objID).Play();
} else {
var c = document.getElementById(objID);
if (c) Obj.mediaDiv.removeChild(c);

var mediaObj = document.createElement("object");
mediaObj.id = "objmedia" + tmp.toString();
mediaObj.setAttribute("type",mphMain["snd"+tmp].datatype);
mediaObj.setAttribute("data",mphMain["snd"+tmp].sndURL);

mphAddParam(mediaObj,"AutoStart","true");

mphObj.mediaDiv.appendChild(mediaObj);
}
}

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

if (Obj.isIE) {
document.getElementById(objID).Stop();
} else {
var c = document.getElementById(objID);
if (c) Obj.mediaDiv.removeChild(c);
}
}
Andrew Poulos
Jul 23 '05 #3

P: n/a
On Sun, 02 Jan 2005 11:48:05 +1100, Andrew Poulos <ap*****@hotmail.com>
wrote:

[snip]
Here's some sample code that I want to convert to a library type
approach.


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.
Jul 23 '05 #4

P: n/a
Michael Winter wrote:
On Sun, 02 Jan 2005 11:48:05 +1100, Andrew Poulos <ap*****@hotmail.com>
wrote:

[snip]
Here's some sample code that I want to convert to a library type
approach.

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

[snip]


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

Thanks for the help.

Andrew Poulos
Jul 23 '05 #5

P: n/a
[snip]
var myLib = (function() {
return {
myMethod1 : function() {
alert('myMethod1 called');
this.myMethod2();
},
myMethod2 : function() {
alert('myMethod2 called');
}
};
})();

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


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
Jul 23 '05 #6

P: n/a
On Mon, 03 Jan 2005 08:59:56 +1100, Andrew Poulos <ap*****@hotmail.com>
wrote:

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


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.
Jul 23 '05 #7

P: n/a
On Mon, 03 Jan 2005 10:48:11 +1100, Andrew Poulos <ap*****@hotmail.com>
wrote:
[...] 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)?


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.
Jul 23 '05 #8

P: n/a
In article
<41***********************@per-qv1-newsreader-01.iinet.net.au>,
Andrew Poulos <ap*****@hotmail.com> wrote:
That means I don't yet understand when a library type approach is
appropriate.


What is the library approach?

Robert
Jul 23 '05 #9

This discussion thread is closed

Replies have been disabled for this discussion.