...

View Full Version : Private Javascript Classes



Bridge
12-31-2011, 07:02 AM
Hi Guys,

What is the best way to create a javascript class that has all its methods and properties private unless I want them to be public?

Many thanks for any help,

S

Philip M
12-31-2011, 07:20 AM
Are you sure you mean Javascript - not Java? Java and Javascript are entirely different programming languages, in spite of the confusingly similar names. Rather like Austria and Australia!

It's important to note that there are no classes in JavaScript. Functions can be used to somewhat simulate classes, but in general JavaScript is a class-less language. Everything is an object. And when it comes to inheritance, objects inherit from objects, not classes from classes as in the "class"-ical languages.

Bridge
12-31-2011, 08:54 AM
Are you sure you mean Javascript - not Java? Java and Javascript are entirely different programming languages, in spite of the confusingly similar names. Rather like Austria and Australia!

It's important to note that there are no classes in JavaScript. Functions can be used to somewhat simulate classes, but in general JavaScript is a class-less language. Everything is an object. And when it comes to inheritance, objects inherit from objects, not classes from classes as in the "class"-ical languages.

No, I do mean Javascript. They have a "new" keyword and constructors etc etc etc. They also have functions (call them methods if you prefer) and properties.

I currently have a class that is a suite of functions that maintain a user table. I do not want ANY of the internals of that object to be visible to the outside world unless I explicitly say so. Currently, they is a significant danger of name clashes and data corruption and general chaos.

Hence my question.

S

Philip M
12-31-2011, 10:23 AM
Suggest you Google for "Javascript scope" and look at the several articles posted, e.g.
http://www.digital-web.com/articles/scope_in_javascript/

chump2877
12-31-2011, 11:25 AM
I do not want ANY of the internals of that object to be visible to the outside world unless I explicitly say so. Currently, they is a significant danger of name clashes and data corruption and general chaos.

Pseudo-class with all "private" members:


function PseudoClass()
{
// "private" properties
var property1 = "foo";
var property2 = "bar";

// "private" methods
var someMethod = function()
{
// Do Something
};

// pseudo constructor
var constructor = function()
{
// Do Something on instantiation
someMethod();
};
constructor();
}

var cs = new PseudoClass;

Keep in mind that JS is inherently "not" private in that anyone can see your code n the browser. But if all of your "class" properties and methods are "local" to PseudoClass, then at least you don't have to worry about naming conflicts with other variables/functions in the global namespace...

Bridge
01-02-2012, 07:32 AM
Hi guys,

After some research I have uncovered quite a bit of interesting information. So I have wrapped it all up into a demo, which may be found below. Comments and improvements welcome. Hope it is of some use to anyone coming across this thread.

S

A simple html page:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<head>
<title>eazyGen - Testing</title>

<script type="text/javascript">
window.onerror=function(msg, url, linenumber){
alert("Error message: " + msg + " URL: " + url + " Line Number: " + linenumber)
return true
}
</script>
<script type="text/javascript" src="TestClass.js"></script>
<script type="text/javascript" src="testHarness.js"></script>

</head>
<body>
</body>

A test harness


// This demo shows the difference between member (data) and function (activity) types in Javascript
// It creates a new instance of the TestClass and then demonstrates what is available
// publicly, privately, and also statically.
//
// Using these techniques will help you write more robust and error free Javascript code
// If anyone sees an error or knows of a better way, please let me know
//
// But please bear in mind that this code has been designed with usability
// in mind as opposed to technical brilliance.
//
// www.eazyGen.com


// Create new instance of the class
test = new TestClass();

// Why? Many reasons:
// A class allows us to have several instances of the same class (objects)
// A class allows us to re-use the code within it without having to code it mroe than once
// A class can allow us to have a robust interface to the data and fuctions within it
// which makes coding easier



// A private member is available within the instance (private) but not outside (public)
alert("Show the private variable : " + test.privateField ); // Shows undefined
// Why?
// A private variable should be just that - private. It may not be changed by anything other
// than the class instances. This ensures that the data cannot be corrupted by mistake



// A public member is available within the instance (private) AND outside (public)
alert("Show the public variable : " + test.publicField); // Shows correct value
// Why?
// There are times when we DO want to change the data inside an object, although
// it may be better to only change this data via a call to a fucntion.
// But this shows how it may be changed by an external function
test.publicField = "I have now changed";
alert("Show the public variable again : " + test.publicField); // Shows new value




// A private function is a fuction that is only available to the class instance (private)
//and may NOT be called from outside (public)
//test.privateFunction() // This would result in a Javascript run time error



// A public function is a fuction that is available publicly
//and may NOT be called from outside (public)
test.publicFunction() // This works


// A privileged function is available publicly, but which also has access to private variables
alert("Show the private variable : " + test.secondPrivateField); // Shows undefined
alert("Show the private variable via a privileged function: " + test.privilegedFunction()); // Shows correct value
// Why?
// A public fuctio allows us to invoke actions, but it is perfectly reasonable to allow
// private data to be made available to public functions. In this way we can alter the values
// of private variables, but oly using the formal functions (or methods) of the class object
// This is good general OO practice.
// Now we will call a public function that alters the private variable
alert("Show the changed private variable : " + test.secondPrivilegedFunction()); // Shows changed value
// Note - I have called these functions "privileged" but, in truth, they are just standard
// functios. But I show them this way to demonstrate how they can manipulate private data



// Retainer variables
// Retainer variables are variables that retain their value between function calls
// This property can be useful when, for example, you want to keep
// track of how many times a function has been called from within the function
// NOTE – I call these “Retainer” variables and NOT “Static” variables,
// because that could confuse them with Static variables in other, more
// OO languages – Java, C++ etc
// They are not the same thing. Static variables in Java and co keep
// track of their value across instances of a class. Retainer variables
// keep track of their value across function calls – which is different
//
// Javascript does NOT support Static variables as used in Java
//
// An alternative would be to use global variables, but retainer variables
// are an improvement on this I believe because they can be kept private and unchangeable
test.staticVariableFuction(); // Returns 1
test.staticVariableFuction(); // Returns the incremented value

// Of course, there is a lot more to this subject, but I hope some of that has been useful.

And a class to operate upon:


function TestClass () { // Declare the class and construct



// This is a PRIVATE field variable only available within constructor
var privateField = "My PRIVATE Field Variable";



// This is a PUBLIC field variable only available within constructor
this.publicField = "My PUBLIC Field Variable";



// A Private function
var privateFunction = function () { // A private function
alert("This is NOT publicly available");
} // End A private function



// A Public function
this.publicFunction = function () { // A public function
alert("This IS a publicly available function");
} // End A public function




// This is a privileged function - one available publicly but which also has access
// to private variable
this.privilegedFunction = function () {
alert("priv function - var is : " + myVar);
}

// This is another private field variable
var secondPrivateField = "Also private";
// This is a public function that gives access to the private field
this.privilegedFunction = function () { // A privileged function
return secondPrivateField;
} // A privileged function

// This is another priviledged function
this.secondPrivilegedFunction = function () { // A second privileged function
secondPrivateField = "Now I have changed too";
return secondPrivateField;
} // A second privileged function



var myNumber = null; // The retainer variable (not that it is private)
this.staticVariableFuction = function () { // Static variable function
// Check to see if the variable has been initialized
if (typeof myNumber == null) { // First time?
// This is the first invokation so let us initialise the "static" variable "number"
myNumber = 0;
} // End First time?
// increment the value
myNumber = myNumber + 1;
alert("The Number is : " + myNumber);
} // End Static variable function


}// End Declare the class and construct

Old Pedant
01-02-2012, 08:13 AM
Ummm...isn't that exactly what RJ showed you in post #5?

But it's still not a "class" in any classical sense of the word. Not when compared to classes in languages such as Java and C++ and C# and ...

Bridge
01-02-2012, 08:28 AM
Ummm...isn't that exactly what RJ showed you in post #5?

But it's still not a "class" in any classical sense of the word. Not when compared to classes in languages such as Java and C++ and C# and ...
It is a broader examination of the issue with extensive comments designed to help others.

Whether it is a class or not matters only in as much as the word is loaded with meaning from other languages and products. As long as it does what you want, what you call it is totally irrelevant.

I can instantiate it.
I can activate functions within it.
I can update data properties.
I can make items public or private.

That's all I really need.

Old Pedant
01-02-2012, 08:37 AM
I'm not at all clear why you classified "retainer variables" as anything special. In essesnce, they are simply private variables that are exposed via public methods. No? What am I missing?

Wouldn't it make as much sense to provide "safe" setter/getter methods and so follow the same patterns as are used in languages such as Java?


function pseudoClass( )
{
var private;
this.getPrivate = function() { return private; };
this.setPrivate = function(value) { if ( ! isNaN(value) ) private = value; };
}

In what way is private here different than a "retainer variable" as you defined it?

Old Pedant
01-02-2012, 08:45 AM
Of course, one problem with JavaScript is that you can't guarantee that your "classes" will work correctly.

For example:


TestClass.prototype.privateFunction = function() { return "aha"; }
var t = new TestClass();
alert( t.privateFunction() );


(Yeah, I know...the idiot who does that deserves what he gets. But still, it's a flaw in the ability to completely encapsulate your "private" coding.)

Bridge
01-02-2012, 08:50 AM
I'm not at all clear why you classified "retainer variables" as anything special. In essesnce, they are simply private variables that are exposed via public methods. No? What am I missing?

Nothing - they are the same - see the comment on the deceleration of myNumber:


var myNumber = null; // The retainer variable (note that it is private)

The difference here is not the nature of the variable but of the manner in which it "retains" its value across function calls. It is a technique rather than a language property. It seemed a useful one to me, which is why I elected to include in the demo.

Wouldn't it make as much sense to provide "safe" setter/getter methods and so follow the same patterns as are used in languages such as Java?


function pseudoClass( )
{
var private;
this.getPrivate = function() { return private; };
this.setPrivate = function(value) { if ( ! isNaN(value) ) private = value; };
}


I only show what is possible. I don't dictate approach. Get and Set are fine by me. Just so long as what is going on is understood and not followed blindly. Javascript is different to Java etc - and I created the demo to highlight some of these differences for the purposes of sharing.

In what way is private here different than a "retainer variable" as you defined it?

See above.



Please see my comments above

Old Pedant
01-02-2012, 08:55 AM
Okay...valid arguments. I admit to trying to keep things as simple as possible, so I tend to try to cut to the lowest common denominator.

I also admit to not using JavaScript for much serious work. 95% of the stuff I do is done server side with JavaScript just used as a GUI assistance mechanism.

chump2877
01-02-2012, 09:00 AM
If you're going to make class members public, then you will also want to consider adding to the prototype as well:

"Prototype is a type of inheritance in JavaScript. We use it when we would like an object to inherit a method after it has been defined. Think of prototyping mentally as "attaching" a method to an object after it's been defined, in which all object instances then instantly share." (excerpt from here (http://www.javascriptkit.com/javatutors/oopjs2.shtml))

If you are creating a lot of instances of your class (i.e., object factory pattern), I believe that prototype is more efficient (in terms of memory usage) than the privileged/public methods that you demonstrated in your example. Because each instance of your class carries around one more member inside of it that could have been designated only once to prototype. (I can't find any documentation on this a the moment, but like I said, i believe this is the case?...)

Edit...
Here we go: http://codebetter.com/petervanooijen/2006/10/31/pragmatic-oop-in-javascript-part-2-to-prototype-or-not-to-prototype/
Check the blurb under the "What's the cost ?" subhead on the page about prototype and memory usage.

In other words, the most scalable approach to javascript oop (in terms of memory efficiency) is to use private members and prototype (for public members) only -- and don't use public/privileged "instance" methods if you dont have to.

Bridge
01-02-2012, 09:08 AM
Okay...valid arguments. I admit to trying to keep things as simple as possible, so I tend to try to cut to the lowest common denominator.

I also admit to not using JavaScript for much serious work. 95% of the stuff I do is done server side with JavaScript just used as a GUI assistance mechanism.

That's perfectly fine Old Pedant - I always try and keep things as simple as possible and I completely agree with you that one should. But I do believe it is very important that one understands the programming model before the syntax because I feel it is only in that way that one can keep things simple. That's why, after my research, I thought I would share my findings with other folk on the forum in a bid to help them.

The split twixt client and server is a huge topic on its own and one of high interest.

I am building an app that has a UI that mimics a regular C++ or Java UI (not because I like them, just for the purposes of standardisation). The app also makes extensive use of asynchronous Ajax calls. So precisely where to draw the client server line is something that exercises me daily.

I do appreciate your questioning my post - it is good to be challenged. But I also hope it may shed a modicum of light.

Good to chat to you.

S

Bridge
01-02-2012, 09:29 AM
If you're going to make class members public, then you will also want to consider adding to the prototype as well:

"Prototype is a type of inheritance in JavaScript. We use it when we would like an object to inherit a method after it has been defined. Think of prototyping mentally as "attaching" a method to an object after it's been defined, in which all object instances then instantly share." (excerpt from here (http://www.javascriptkit.com/javatutors/oopjs2.shtml))

If you are creating a lot of instances of your class (i.e., object factory pattern), I believe that prototype is more efficient (in terms of memory usage) than the privileged/public methods that you demonstrated in your example. Because each instance of your class carries around one more member inside of it that could have been designated only once to prototype. (I can't find any documentation on this a the moment, but like I said, i believe this is the case?...)

Edit...
Here we go: http://codebetter.com/petervanooijen/2006/10/31/pragmatic-oop-in-javascript-part-2-to-prototype-or-not-to-prototype/
Check the blurb under the "What's the cost ?" subhead on the page about prototype and memory usage.

In other words, the most scalable approach to javascript oop (in terms of memory efficiency) is to use private members and prototype (for public members) only -- and don't use public/privileged "instance" methods if you dont have to.

Thank you.

I deliberately omitted to mention prototype. For singleton "classes" I am struggling to think of why I would use it.

For factory objects it may be different. But let's think about it for a moment. As far as I know the use of prototype allows object instances to share the implementation of the prototype members not the values. The values must be specific to the instances so I am not entirely sure what performance gains are to be had. Even if there are gains, what effective difference would they make I wonder?

I also think that prototype may (I only say "may") lead to bad practice. Why do you want to attach (call it inherit if you wish) a method to an object at run time. Why have we not designed our "classes" correctly ahead of time? We would have to do it using Java (extend) in order to benefit from that language's implementation of inheritance !!

I would be interested to hear of any answers to this.

Good discussion - thanks.

S

chump2877
01-02-2012, 09:59 AM
For singleton "classes" I am struggling to think of why I would use it.

If you are only ever dealing with singleton classes, then I am inclined to agree with you. Prototype isn't necessary in that case.


As far as I know the use of prototype allows object instances to share the implementation of the prototype members not the values. The values must be specific to the instances so I am not entirely sure what performance gains are to be had.

That's an interesting notion, and I don't really have an answer for you. Generally, I find myself using prototype to attach methods (and not properties), and methods don't carry around values (afaik). So if there is no advantage to attaching properties to prototype, I would be interested in hearing more about this...perhaps some links to websites where I can read more? :)


I also think that prototype may (I only say "may") lead to bad practice. Why do you want to attach (call it inherit if you wish) a method to an object at run time. Why have we not designed our "classes" correctly ahead of time?

Let's not forget that Js is not an oop language -- it is a prototype language that can be pulled and stretched to somewhat resemble oop. So the normal arguments for oop don't really apply to Javascript. And because things like memory and memory leaks are so important here, sometimes the best looking code does not equate to the most efficient code.

Bridge
01-02-2012, 10:15 AM
If you are only ever dealing with singleton classes, then I am inclined to agree with you. Prototype isn't necessary in that case.



That's an interesting notion, and I don't really have an answer for you. Generally, I find myself using prototype to attach methods (and not properties), and methods don't carry around values (afaik). So if there is no advantage to attaching properties to prototype, I would be interested in hearing more about this...perhaps some links to websites where I can read more? :)



Let's not forget that Js is not an oop language -- it is a prototype language that can be pulled and stretched to somewhat resemble oop. So the normal arguments for oop don't really apply to Javascript. And because things like memory and memory leaks are so important here, sometimes the best looking code does not equate to the most efficient code.

I think I would agree with all of that :)

S

rnd me
01-02-2012, 10:50 AM
Let's not forget that Js is not an oop language -- it is a prototype language that can be pulled and stretched to somewhat resemble oop.

Just because JS is not like some other language's implementation of objects doesn't mean it's not completely object based, don't be fooled.
Objects are what's being prorotyped. you might argue that prototypal and classical inheritance are mutually-exclusive, but oop and prototyped objects are not.
With the addition of Object.create() / property descriptors (working in all browsers since IE8) it actually has many features like concealment and rigidity that many classical programmers find familiar.


to answer the question about prototypes, they help performance.
it's important to note that all objects of a class share the exact same prototype object. if that object contains 10 member methods that operate on "this.x" syntax, and you instantiate 1000 objects, that's 9,990 fewer function objects to instantiate, 9,990 fewer properties to own and attach, and 9,990 fewer objects floating in RAM during runtime. on weak systems such as an ipad, these subtle design choices can have profound performance and thus UX ramifications.

I think of primitive prototypes as "right of the dot globals" and prototyped object methods as "right of the dot locals"

still, 90% of the things you could use a prototype method for, you can also just use a closed function on. i find the resulting code easier to read , write, and debug.
if you make a constructor constructor, your object can share lexical scope (named variables) instead of this.x'ing everything...
however, you don't want to close DOM methods/objects, which are also traditionally the slowest operations. this makes DOM interaction more suitable for prototypes than closure.

Bridge
01-02-2012, 11:20 AM
Thank you for that.

Do you happen know of a good source that describes accurately the performance attributes of Javascript / DOM access / Sizzle et al please?

Many thanks if you do,

S

chump2877
01-02-2012, 12:39 PM
With the addition of Object.create() / property descriptors (working in all browsers since IE8) it actually has many features like concealment and rigidity that many classical programmers find familiar.


I've seen that stuff recently, and it looks nice. Haven't had a chance to use it yet though because my current project must work in IE7.

In case you're curious, here is browser compatibility table for the new Object methods/properties: http://kangax.github.com/es5-compat-table/

I noticed in this table that it shows IE8 as having very little compatibility with them. Opening that compat table in IE8 seems to confirm this? Is this table completely accurate?


however, you don't want to close DOM methods/objects, which are also traditionally the slowest operations. this makes DOM interaction more suitable for prototypes than closure.

Are you advocating extending the prototypes of DOM objects? Or are you just saying that the DOM makes extensive use of prototype? Or that the use of prototype in your own custom classes is better suited to interaction with the DOM?

rnd me
01-03-2012, 11:32 PM
Are you advocating extending the prototypes of DOM objects? Or are you just saying that the DOM makes extensive use of prototype? Or that the use of prototype in your own custom classes is better suited to interaction with the DOM?


i could have been a liuttle clearer on that.
im saying that complex apps often use document.createElement() to build UI.

When using object pointers to those dynamic elements, myInstance.updateDisplay() is better for performance than a private updateDisplay(myInstance) method would be. because you can/must/should use "pure function"s in prototype methods (no closures), you avoid memory leaks and memory waste by not creating private dom object-closing methods...

oh, and yeah, ie8 is not 100% supportive. but saying "ie8" gets people to look it up instead of dismissing it as "a 9 thing"...
i don't use dom extensions, but if i finally dumped jQuery, i would be using them a lot, since they DO work in IE8 (i swear this time).

chump2877
01-04-2012, 12:03 AM
When using object pointers to those dynamic elements, myInstance.updateDisplay() is better for performance than a private updateDisplay(myInstance) method would be. because you can/must/should use "pure function"s in prototype methods (no closures), you avoid memory leaks and memory waste by not creating private dom object-closing methods...

How much better is performance when using prototype methods vs. private methods to operate on instances of DOM objects? Does it depend on the number of DOM object instances? (I'm guessing that it does?)

Also, while prototype may be better for performance in this case, isn't it bad practice to extend the prototype of DOM objects? (Because the DOM is implemented differently in different browsers, etc....)

rnd me
01-04-2012, 04:11 PM
im wasn't really talking about dom extensions, but rather simply using prototype methods of regular custom objects (from Constructors) to manipulate the dom.

for example, if you had a person object, you might have a custom method on that object: updateOnlineStatus(). this could change an input checkbox according to weather a user is signed-on or not. rather than have this method point to a variable, it should point to this.statusInput, or something along those lines. Again, this is mainly to reduce memory leaks resulting from greedy closures, and to ensure you don't create extra personalized pointers in the case when a single public set can be shared.

the performance boost comes from reduced RAM usage, not really from CPU reduction...

if you're app is an informational display type, and you don't expect the page to be open for more than an hour, don't worry so much about architecture; about anything should work. If you are designing a constant-on dynamically updated "perma-tab", like gmail, then put in the effort to start on a solid and streamlined programming model.

if you can live without IE7, consider DOM extensions. or, you can use dom extensions to turn everything into the IE7 dom's shape (.innerText, event.srcElement, etc).

chump2877
01-05-2012, 09:34 AM
im wasn't really talking about dom extensions, but rather simply using prototype methods of regular custom objects (from Constructors) to manipulate the dom.

for example, if you had a person object, you might have a custom method on that object: updateOnlineStatus(). this could change an input checkbox according to weather a user is signed-on or not. rather than have this method point to a variable, it should point to this.statusInput, or something along those lines. Again, this is mainly to reduce memory leaks resulting from greedy closures, and to ensure you don't create extra personalized pointers in the case when a single public set can be shared.

Can you give me a code example for this? My feeble mind is having trouble understanding exactly what you are saying here. ;)


If you are designing a constant-on dynamically updated "perma-tab", like gmail, then put in the effort to start on a solid and streamlined programming model.

that's a good point.


if you can live without IE7, consider DOM extensions. or, you can use dom extensions to turn everything into the IE7 dom's shape (.innerText, event.srcElement, etc).

When you say "dom extensions", what exactly are you referring to?

rnd me
01-05-2012, 06:47 PM
Can you give me a code example for this? My feeble mind is having trouble understanding exactly what you are saying here. ;)

When you say "dom extensions", what exactly are you referring to?



it's complex to code up a good demo, so this won't be convincing, but it is indicative of the pattern that WILL be better in complex apps.


this code:

var Person=(function(){
var people={};
var cont=document.createElement("div");
cont.id="activeperson";
document.body.appendChild(cont);


function Person(name){
this.name=name;
people[name]=this;
}
Person.prototype.updater=function(){
cont.innerHTML=this.name;
}

return Person;

}());



var bob=new Person("bob");
var john=new Person("john");
bob.updater()
john.updater()

is a lot better than this code:

var Person=(function(){
var people={};
var cont=document.createElement("div");
cont.id="activeperson";
document.body.appendChild(cont);


function Person(name){
this.name=name;
people[name]=this;
this.updater=function(){
cont.innerHTML=this.name;
};
}

return Person;

}());

why?
the first code has one closure around the dom object, the 2nd one has 2 closures and one extra method copy for every person instance compared to the prototyped one.


subtle yet significant...



"dom extensions" mean augmenting the prototypes of element constructors like Element.

chump2877
01-06-2012, 02:56 PM
Going back to this for a moment:


if you make a constructor constructor, your object can share lexical scope (named variables) instead of this.x'ing everything...

What exactly do you mean by a "constructor constructor"? Is this an example of one:


var Person = (function(){
var pName;
function Person(pname)
{
pName = pname;
}
return Person;
}());

So, in other words, you name your class with 'var Person' and then 'function Person' serves as your constructor? If so, I love it! If you hadn't noticed, up until now I had been finagling a class constructor by doing the following:


function Person(pname)
{
var pName;
var constructor = function()
{
pName = pname;
};
constructor();
}

Are these 2 class constructor examples functionally equivalent (and in fact both "constructor constructors")? Is one version better than the other? (In the examples, I tried to illustrate that this:


your object can share lexical scope (named variables) instead of this.x'ing everything

...appears to be true for both examples with the 'pName' variable. I hope that's what you meant?)


*Edit: I have just noticed one thing. This code:


Person.prototype.updater=function(){
// some code
}

Would work inside the former example, but not in the latter example. So I like that I can now declare my prototype functions inside (instead of outside) of the class [constructor]! Makes for more readable code...Plus, prototype functions declared in this way also have access to local vars (private and privileged class members) declared in the outer Person function/class. Too cool! I'm geeking out over here ;)


Now, with respect to prototype and closures:


the first code has one closure around the dom object, the 2nd one has 2 closures and one extra method copy for every person instance compared to the prototyped one.

I think I am understanding now. So the fact that there is one less closure around the DOM object 'cont' in the first example means that there is one less pointer/reference to 'cont' in the code. Right?

And Person.prototype.updater() in the first example could easily be replaced with this.updater(), and still maintain only one closure around the DOM object. But by using prototype there instead of a privileged member function, we also get the enhanced benefit of one less function copy attached to each Person instantiation. Right?

So the bottom line here is that judicious manipulation of closure coupled with the judicious use of prototype (especially with respect to DOM objects) ultimately results in fewer memory leaks in a javascript-intensive, "constant-on" type of application. Right?

Now the hard part is recognizing and being aware of these concepts "while" I am writing my code ;)


And finally:


"dom extensions" mean augmenting the prototypes of element constructors like Element.

I still don't understand why extending DOM object prototype makes sense if the DOM is unpredictable -- in that it is implemented differently in different browsers. See here (http://perfectionkills.com/whats-wrong-with-extending-the-dom/). Per that article, DOM object "wrappers" make much more sense to me. Unless the use of wrappers is actually what you were trying to say?


Thanks for the illuminating post(s). I am learning a lot here. :thumbsup:

rnd me
01-06-2012, 10:21 PM
What exactly do you mean by a "constructor constructor"? Is this an example of one:


var Person = (function(){
var pName;
function Person(pname)
{
pName = pname;
}
return Person;
}());

So, in other words, you name your class with 'var Person' and then 'function Person' serves as your constructor? If so, I love it!
In that code, var Person === function Person. with your code you just posted, you execute two functions to invoke a class; i invoke one function at boot, and one per class instantiation.



think of it this way: we all know that it's easy to program using a ton of globals; less parameter passing, simpler execution flows, greater readability, less typing, the list goes on and on. but, we also know that globals are bad; each one rolling the dice on a name conflict among other things.

The solution i use is what i call a pseudo-global; a wrapper function creates a temporary lexical scope that you can slop plenty of vars down into. these var won't be globals, and won't reach outside the function. But, if the function returns the only thing you need anyways, and if that thing is a function, your returned function will closure all the needed "pseudo-globals" and run as expected. it's the best of both worlds at a very slight closure memory cost, which is generally not worth worrying about.

In this example, i create a temporary lexical scope using an anon function that returns the constructor (and all it's closings) that i wanted.

I can also store common methods and variables in the prototype object and these too will be reachable by all instances of a class. either the prototypes or the psudeo-globals are single objects used by many. i just get tired of typing this.everything...



So the fact that there is one less closure around the DOM object 'cont' in the first example means that there is one less pointer/reference to 'cont' in the code. Right?
yes; the private this.updater() would store it onw copy of the function, and that copy closes the dom object. compared to one public .updater() that has one closure.




by using prototype there instead of a privileged member function, we also get the enhanced benefit of one less function copy attached to each Person instantiation. Right?
yes, the actual object should contain a bare-minimum of data, while prototype methods should be able to process that data for any given object.




So the bottom line here is that judicious manipulation of closure coupled with the judicious use of prototype (especially with respect to DOM objects) ultimately results in fewer memory leaks in a javascript-intensive, "constant-on" type of application. Right?
yes. closures, especially on DOM objects are problematic over the long haul. while the permanent memory leaks (browser restart) went away with IE6, the session (page refresh) memory leaks are still a big problem with sloppy and/or long-running code.





Per that article, DOM object "wrappers" make much more sense to me. Unless the use of wrappers is actually what you were trying to say?
no. wrappers are slow. i mean extending the Element or sub-Element prototypes, just like the article says not to. Again, if you don't care about IE7 and older browsers, you can do really cool stuff with very little code. When that article was written, IE7 was probably at about 50% share. now it's 5-10%, and this developer has moved on.

chump2877
01-22-2012, 05:30 AM
Sorry it took forever for me to respond to this. Been rather busy around here...

Here is my new blueprint for JS OOP (per your suggestions):


// Employee class
var Employee = (function(){
//region Define Private Fields
var empName = 'default';
//endregion

/* Class Constructor */
function Employee(name)
{
//region Define Public (Privileged) Fields/Properties
this.prop = 'val';
this.name = name;
//endregion

empName = name;
}

//region Define Public Methods (in contructor prototype)
Employee.prototype.someMethod = function()
{
return anotherMethod(empName);
};
//endregion

//region Define Private Methods
var anotherMethod = function(name)
{
return name;
};
// endregion

return Employee; // return class constructor and all class members (public members stored in constructor object prototype, pivileged members directly in constructor object, and private members in closure)
}());

/* Tests to illustrate a new class instance is required */
//alert(Employee.prop);
//alert(Employee.someMethod());

/* Tests to illustrate object instance members */
var emp = new Employee("Joe");
alert(emp.name);
alert(emp.prop);
alert(emp.someMethod());

...keeping in mind that logic related to the manipulation of dynamically-generated DOM objects should ideally be stored in prototype methods using the fewest closures possible.

Look right to you?


no. wrappers are slow. i mean extending the Element or sub-Element prototypes, just like the article says not to. Again, if you don't care about IE7 and older browsers, you can do really cool stuff with very little code. When that article was written, IE7 was probably at about 50% share. now it's 5-10%, and this developer has moved on.

What if HTML 6 introduces a new DOM prototype function named "function" for element "X" (for example! -- ignore the ridiculous names). But you have already defined a X.prototype.function() in your HTML 5 code. Isn't the potential for conflict there (in future versions or even different implementations of the DOM)? Isn't that potential conflict, and the potential of refactoring large amounts of code in the future, enough to offset the slower speeds of wrappers? How much slower are wrappers anyway? Why exactly are they slower?

Bridge
01-22-2012, 10:51 AM
A bit of waffle first and then a question.

I have been building commercial systems for longer than am prepared to say. I started on an IBM with COBOL 74 which only allowed a program to occupy 64k of memory before I had to start programatically paging stuff in and out. So I am not downplaying the importance of writing code that performs well. I have spent my life with at least one eye on performance.

However, sometimes (stressed) high performance code can be less easy to read - which can cause problems of a different nature.

So my question is this: I accept all the discussion above; I tip my hat at the thought that has gone in; I bow to the experience shown; and I take most of the points.

But what happens when the user just goes out and buys 8GB more memory?

S

Philip M
01-22-2012, 11:34 AM
But what happens when the user just goes out and buys 8GB more memory?

S


Can you add more memory to a mobile device?

Bridge
01-22-2012, 11:39 AM
Can you add more memory to a mobile device?

No - but then I am not targeting a mobile platform. And anyway, who knows what you will be able to do with those things next year?

S

chump2877
01-22-2012, 06:09 PM
However, sometimes (stressed) high performance code can be less easy to read - which can cause problems of a different nature.

I guess I don't really consider my new blueprint for JS OOP that hard to read. It's not like any implementation of JS OOP is similar to OOP implementations in C#, Java, PHP, etc.. So if you can get past these differences, and in fact understand/appreciate these differences, then what's not to understand?


But what happens when the user just goes out and buys 8GB more memory?

Interesting point, and I don't have an answer for that really. It would certainly seem that more RAM might counter the effects of memory leaks in most cases. But a couple of thoughts come to mind:

1) In my experience, even with 8 GB of RAM in my computer -- a memory leak in a browser, if left to fester for a day or 2 without closing the browser, can still cause significant lagging inside the browser.

2) If we are dealing with a "constant-on" type of application, and the browser is not closed for days on end, is more RAM really the solution? Or should we take a closer look at the code instead?

3) Again, in my experience, developing for the Internet is about accessibility -- creating an equivalent experience for the most number of users regardless of their browser, OS, and hardware configuration.

Even if a significant percentage of users added more RAM to their systems, what happens to the people that don't?

(If you can control the client configuration, as in an Intranet, then this might not be an issue. But creating a resource to be consumed on the public Internet is different because client configuration is unpredictable.)

4) Even for an Intranet, what is the cost of increasing RAM versus the cost of writing better code? Who knows, I guess?

Bridge
01-23-2012, 03:27 AM
I guess I don't really consider my new blueprint for JS OOP that hard to read. It's not like any implementation of JS OOP is similar to OOP implementations in C#, Java, PHP, etc.. So if you can get past these differences, and in fact understand/appreciate these differences, then what's not to understand?

I do take your point in this case. I did stress that it reads harder only sometimes.

Interesting point, and I don't have an answer for that really. It would certainly seem that more RAM might counter the effects of memory leaks in most cases. But a couple of thoughts come to mind:

1) In my experience, even with 8 GB of RAM in my computer -- a memory leak in a browser, if left to fester for a day or 2 without closing the browser, can still cause significant lagging inside the browser.

I do agree, but I feel there is a difference between some code that performs badly, and some code that causes the dreaded memory leak. In the former case I am more relaxed, in the latter case, less so.

2) If we are dealing with a "constant-on" type of application, and the browser is not closed for days on end, is more RAM really the solution? Or should we take a closer look at the code instead?

I don't think we have "constant-on" type applications, more "constant-on" type users. Now, if I am building a noddy web site that contains a few images and some contact details, then I don't really consider "constant-on" type anything. If I am building a beast of an app (which I am), then I spend a LOT of time on the big ticket items - memory usage, network calls, and IO routines. But this app is not for Joe Public, so I am content, in a way, that they won't leave a browser open for days on end.

I suppose the third type is the tricky apps that ARE for Joe Public - Tesco shopping for example - a nice piece of work in my view; that would have needed a LOT of thought. But you can only support so many browsers and versions (Tesco's site didn't work in FF for a while I noted), and you can't cater for the guy who keeps his computer on for years so that it runs slower than a snail. He just needs to learn to reboot now and again.

3) Again, in my experience, developing for the Internet is about accessibility -- creating an equivalent experience for the most number of users regardless of their browser, OS, and hardware configuration.

Even if a significant percentage of users added more RAM to their systems, what happens to the people that don't?

Point taken. So, we group our apps around the target audience. We asses the range of technology they will have and we will support, and we asses the range of behaviors they will display and we will manage. Then we lay in our plans accordingly.

(If you can control the client configuration, as in an Intranet, then this might not be an issue. But creating a resource to be consumed on the public Internet is different because client configuration is unpredictable.)

Agreed - I am lucky in as much as I know my target audience will have goodish machines, standardised ish, and inside an intranet.

4) Even for an Intranet, what is the cost of increasing RAM versus the cost of writing better code? Who knows, I guess?

I also take point 4 too. But I would also suggest that there are other costs and issues to worry about. Let's say I am managing a project inside an intranet. I want:

1. Yes, good code. But it must be understandable by others in the team.
2. A broad and public set of standards so that ALL are singing from the same song sheet.
3. Good team organisation etc

But the thing I want MOST of all, is my people thinking about the user requirements and how the system meets those and NOT thinking about how we can shave a few mips here and there by tweaking some esoteric code into something that breaks the rules stated above.

In my experience as a project manager (considerable) programmers spend WAY too much time thinking about technology and NOT about what the user actually wants and needs. This is a MASSIVE cost in both the short and long term.

A guy who simply turns a coding spec into a program is no good to me as a project manager. And, in my view, I am no good as a project manager, if I structure the project in such a way.

Sorry if I wandered a bit there, but it is all connected for me.

S

chump2877
01-23-2012, 04:14 AM
In a nutshell, I don't think the interpretation/implementation of user requirements has to suffer at the cost of writing better, more efficient code. Writing good code should be so ingrained in developers that it becomes second nature and virtually effortless. If it isn't second nature, then that is another problem entirely.

Bridge
01-23-2012, 04:23 AM
In a nutshell, I don't think the interpretation/implementation of user requirements has to suffer at the cost of writing better, more efficient code. Writing good code should be so ingrained in developers that it becomes second nature and virtually effortless. If it isn't second nature, then that is another problem entirely.

I couldn't agree more, but experience has taught me that this is rarely the case. Especially since the advent of the internet as coding has become open to more and more people.

The majority of the time coding is an arcane and personal act, instead of an engineering discipline, which it should be.

OO helped - a bit. But most (all) languages fail to address this fundamental problem. Until we get a language that enforces rigor and discipline (and Java, C# et al go nowhere near doing this properly), software will be error prone, difficult, and very, very expensive.

Still, we can make a living I suppose.

S



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum