473,698 Members | 2,503 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

object augmentation and memory usage

I have a script which uses a lot of object augmentation (in order to
extend the functionality of DOM elements), and I'm clearly stressing
out my browser (I rapidly get to a point where Firefox is telling me
that the script is "unresponsi ve", often more than once. I'm not sure
if it's simply execution time or memory usage.

My question is this: if I augment an object thusly:

function TestAug() {
this.fun = function() {
//do something
}
}

function Test() {
var test = new Object();
TestAug.call(te st);
return test;
}

Then I create, oh, 800 Test objects, what is my memory usage? Are
augmented members, such as fun, only stored in a single place, and
merely accessed as instance methods through the magic of call, or is
call basically adding a whole new copy of the function, with attendant
time/memory usage, to the object passed to it? The books and resources
I've found all discuss memory issues around class methods, instance
methods, prototyping, etc., but are vague in discussing how call works.

Jan 26 '06 #1
8 1741
Gawain Lavers wrote:
I have a script which uses a lot of object augmentation (in order to
extend the functionality of DOM elements), and I'm clearly stressing
out my browser (I rapidly get to a point where Firefox is telling me
that the script is "unresponsi ve", often more than once. I'm not sure
if it's simply execution time or memory usage.
The warning message is due to run-time always. However, the latter may be
affected by increased memory usage, forcing the operating system to enlarge
the swap file or to do more swapping than usual.
My question is this: if I augment an object thusly:

function TestAug() {
this.fun = function() {
//do something
}
}

function Test() {
var test = new Object();
TestAug.call(te st);
return test;
}

Then I create, oh, 800 Test objects, what is my memory usage?
A considerably large one.
Are augmented members, such as fun, only stored in a single place, and
merely accessed as instance methods through the magic of call, or is
call basically adding a whole new copy of the function, with attendant
time/memory usage, to the object passed to it?


With this approach, the creation of each new object `o' creates a new
Function object (that `o.fun' refers to) via the `function' expression
in turn. Use prototype objects to avoid that:

function TestAug()
{
}

TestAug.prototy pe.fun = function()
{
// do something
}

var test = new TestAug();
PointedEars
Jan 26 '06 #2
Thomas 'PointedEars' Lahn wrote on 26 jan 2006 in comp.lang.javas cript:
The warning message is due to run-time always.


Eh?

--
Evertjan.
The Netherlands.
(Please change the x'es to dots in my emailaddress)
Jan 26 '06 #3
Yeah, prototype is clearly ideal, but I unfortunately don't have that
option -- perhaps a more clear example:

function DivAug() {
this.fun = function() {
//do stuff
}
}

function MyDiv() {
var div = document.create Element('div');
DivAug.call(div );
return div;
}

The idea I had was that rather than create an external infrastructure
which would manage my DOM structure, I would simply augment the DOM
elements so that they would know what to do with themselves.
Unfortunately, I can't muck with a DOM element's prototype. If call
creates a new copy of the functions methods with invocation, I guess
I'm going to have to rethink everything from scratch. Thanks for the
(albeit disappointing) info.

By the way, does this not render object augmentation essentially
useless in all but trivial cases?

Jan 26 '06 #4
VK

Gawain Lavers wrote:
My question is this: if I augment an object thusly:

function TestAug() {
this.fun = function() {
//do something
}
}

function Test() {
var test = new Object();
TestAug.call(te st);
return test;
}
Any particular reason to make the approach so... interesting? ;-)
function foobar() {
// do something
}

function SuperAug() {
this.bar = 'bar';
}

function TestAug() {
SuperAug.call(t his);
this.foo = function() {
//do something
}
this.foobar = foobar;
}

function test() {
glbStack = new Array();
for (var i=0; i<10000; i++) {
glbStack.push(n ew TestAug());
}
alert('Created '+glbStack.leng th+' instances of TestAug');
}

Then I create, oh, 800 Test objects, what is my memory usage? Are
augmented members, such as fun, only stored in a single place, and
merely accessed as instance methods through the magic of call, or is
call basically adding a whole new copy of the function, with attendant
time/memory usage, to the object passed to it?
In the sample above each of 10,000 TestAug instances has its own copy
of foo() method, its own copy of bar property (inherited from SuperAug)
and there is one copy of foobar method for all 10,000 instances.
The books and resources
I've found all discuss memory issues around class methods, instance
methods, prototyping, etc., but are vague in discussing how call works.


It is understandable because call(), apply(), .constructor, instanceof
are members of other dark side of JavaScript which is not suitable to
discuss in a rifined society. :-)

An understandable description may require some terrible words to
pronounce. Without these words an understandable description is as
difficult as qrfpevor gur vagrepbhefr cebprff jvgubhg hfvat gur jbeq
CRAVF.

:-)

But fully prototype-based inheritance is also well accepted and
functional option.

Jan 26 '06 #5
VK

Gawain Lavers wrote:
Yeah, prototype is clearly ideal, but I unfortunately don't have that
option -- perhaps a more clear example:

function DivAug() {
this.fun = function() {
//do stuff
}
}

function MyDiv() {
var div = document.create Element('div');
DivAug.call(div );
return div;
}

The idea I had was that rather than create an external infrastructure
which would manage my DOM structure, I would simply augment the DOM
elements so that they would know what to do with themselves.
Unfortunately, I can't muck with a DOM element's prototype. If call
creates a new copy of the functions methods with invocation, I guess
I'm going to have to rethink everything from scratch.


You will have to rethink your approach but not because of call() -
call() merely replaces constructor context, so is it going to be a
static method or not depends on constructor, not on call() usage.

The catch is that at least IE doesn't allow you to treat DOM elements
like JavaScript Objects (like one you're getting from new Object() ).
What you can is:

1) add allowed event listeners to a DOM element.
2) attach external behaviors to DOM element (IE only)
3) create JavaScript objects having DOM elements as their members

The last approach may work universally for you. Say:

function AmazingDIV() {
this.$ = document.create Element('DIV');
// ...
this.addTo = function(trg) {trg.appendChil d(this.$);}
}

var myDIV = new AmazingDIV();
myDIV.addTo(doc ument.body);

And you are welcome to make addTo method static.

Jan 27 '06 #6
Gawain Lavers wrote:
Yeah, prototype is clearly ideal, but I unfortunately don't
have that option -- perhaps a more clear example:

function DivAug() {
this.fun = function() {
//do stuff
}
}
The comment "do stuff" may not provide enough clarity as inner functions
(declarations or expressions) have a specific role in javascript in that
their use may forms closures:-

<URL: http://www.jibbering.com/faq/faq_notes/closures.html >

In this case it is difficult to see any advantage in using an inner
function expression as the outer function does not have any parameters,
local variables or inner function declarations, so the inner function's
'environment' is empty. Because inner functions may form closures it is
necessary for each such function object to be unique. The language's
specification allows function objects to be re-used when it is
impossible to externally observe the difference between a re-used
function object and two instances of a function object. The observable
difference would relate to the function's internal [[Scope]] property,
and your inner functions would have indistinguishab le [[Scope]]
properties because their outer function has no parameters, local
variables or inner function declarations. So it would be possible for an
ECMAScript implementation to execute your code and not be creating a new
function object with each execution of the - DivAug - method. However,
experimentation has revealed no evidence of any ECMAScript
implementations that take advantage of this permitted optimisation.

Generally, you would not want to use an inner function at all unless you
were taking advantage of its special status as an inner function, and
the closure formed by its creation/use.
function MyDiv() {
var div = document.create Element('div');
DivAug.call(div );
return div;
}

The idea I had was that rather than create an external
infrastructure which would manage my DOM structure,
I would simply augment the DOM elements so that they would
know what to do with themselves.
Without any specific example it is not practical to say anything about
this idea.
Unfortunately, I can't muck with a DOM element's prototype.
You certainly cannot on most browsers, which is practically the same as
not being able to at all.
If call creates a new copy of the functions methods with
invocation,
Don't blame this on the function's call method, it is true of inner
functions on all outer function calls. And it is a valuable and
exploitable feature of the language.

And you don't need to use the call method here (indeed you almost never
need to use the call method).
I guess I'm going to have to rethink everything from scratch.
Not at all. You just need to augment all the DIV elements created with
references to a single function object. You could define that function
globally:-

function forDivFun(){
//do stuff
}

- and either directly augment the DIVs following creation:-

var div = document.create Element('div');
div.fun = forDivFun;

- or have another function do the augmentation:-

function DivAug(div){
div.fun = forDivFun;
}

You probably will not want to (should not want to) define the functions
that will act as methods of your objects globally, but you have many
methods of creating such method in a 'private' scope. For example, the
inline execution of a function expression:-

var divAug = (function(){
function forDivFun(){
//do stuff
}
function forDivBar (){
//do more stuff
}
return (function(div){
div.fun = forDivFun;
div.bar = forDivBar;
});
})();

The inline execution of the function expression only happens once (as
the script loads) so the inner functions - forDivFun - and - forDivBar -
are only created once, but the function returned and assigned to the
global - divAug - variable is able to assign references to those
function object instances to all the DIVs passed to it as arguments (-
divAug(div) -).

The main drawback with the inline execution of a function expression is
that you cannot use the - divAug - function until after the source code
for it has been executed, so the order of the code becomes important
(rarely a significant problem).

An alternative 'private' scope strategy is the "Russian doll" pattern
(named as such because the outer aspect of a function is replaced with
smaller, more specific, inner aspect during its execution):-

fucntion divAug(div){
function forDivFun(){
//do stuff
}
function forDivBar (){
//do more stuff
}
(divAug = (function(div){
div.fun = forDivFun;
div.bar = forDivBar;
}))(div);
div = null;
}

When this function is called for the first time (as - divAug(div); - the
two inner functions - forDivFun - and - forDivBar - are created and then
the global - divAug - function is replaced with an inner function that
has access to - forDivFun - and - forDivBar -. This new function is
called, passing on the div parameter of the outer function so it may be
augmented. Finally the - div - parameter is assigned null so that no DOM
element references are preserved in the closure.

Following the first call to the above function all subsequent calls
transparently execute only the inner function that replaced it. (Thus
the to - forDivFun - and - forDivBar - function objects are only created
once but may be assigned to all DIVs to be augmented).

This strategy means that the set-up/configuration of the divAug function
is delayed until its first use.
Thanks for the (albeit disappointing) info.

By the way, does this not render object augmentation
essentially useless in all but trivial cases?


Augmentation is completely viable, though augmenting 800+ DOM elements
seems a bit extreme. But ore information/context would be needed to
fairly judge the idea.

Richard.
Jan 27 '06 #7
Gawain Lavers wrote:
Yeah,
"Yeah"?

<URL:http://jibbering.com/faq/faq_notes/pots1.html#ps1P ost>
<URL:http://www.safalra.com/special/googlegroupsrep ly/>
prototype is clearly ideal, but I unfortunately don't have that
option -- perhaps a more clear example:

function DivAug() {
this.fun = function() {
//do stuff
}
}

function MyDiv() {
var div = document.create Element('div');
DivAug.call(div );
return div;
}

The idea I had was that rather than create an external infrastructure
which would manage my DOM structure, I would simply augment the DOM
elements so that they would know what to do with themselves.
Unfortunately, I can't muck with a DOM element's prototype.
You can in Gecko-based UAs. And in all other UAs, the above is error-prone
as you are trying to augment a _host object_ [referred to by `div' in
MyDiv() and `this' in DivAug()]. In ECMAScript implementations , a host
object may implement the internal [[Put]] method required to add a property
to an object or change the property value different than specified or not
at all.
[...]
By the way, does this not render object augmentation essentially
useless in all but trivial cases?


No, it does not, for appropriate values of "trivial".
PointedEars
Jan 27 '06 #8
Richard Cornford wrote:
You probably will not want to (should not want to) define the functions
that will act as methods of your objects globally, but you have many
methods of creating such method in a 'private' scope. For example, the
inline execution of a function expression:-
And that nails my problem exactly -- I knew full well how to attach a
function in that manner, but had just screened it out mentally because
I didn't want to "pollute" the global namespace. In retrospect, it was
foolish for me to not figure out how call() would behave if I defined
inner functions in that manner.
var divAug = (function(){
function forDivFun(){
//do stuff
}
function forDivBar (){
//do more stuff
}
return (function(div){
div.fun = forDivFun;
div.bar = forDivBar;
});
})();
<snip>
fucntion divAug(div){
function forDivFun(){
//do stuff
}
function forDivBar (){
//do more stuff
}
(divAug = (function(div){
div.fun = forDivFun;
div.bar = forDivBar;
}))(div);
div = null;
}
That took me a while to figure out, but that's pretty much exactly what
I need. Cryptic, but fun. For the moment I've just wrapped the
methods for my augmenting "classes" in simple objects, but I'll
probably start trying this out soon. I'm still getting one or two
warnings on occasion in Firefox, but that's on an underpowered laptop.
Augmentation is completely viable, though augmenting 800+ DOM elements
seems a bit extreme. But ore information/context would be needed to
fairly judge the idea.

Richard.


It's a part of an internal web application where users score observed
genetic expression from experimental results. The 800+ actually refers
to a listing of anatomy features (from system to organ to organ
sub-region to cell type) -- each of these having a number of data
points that the users need to be able to set -- about 20 or so "active"
html elements being used to provide pulldown menus, links, and form
fields for each anatomy feature. The scoring widgets themselves are
somewhat complex, and choices in one part of the tree can influence
scores in other parts. Fortunately, as an internal thing, I have a
certain amount of control over things like browser and cpu, but the key
was for it to be faster and easier than the previous version, which
relied entirely on server side scripting and form submissions
(reloading the page every time a branch was expanded, etc.).

Anyway, thanks a lot for the help (everyone). Problem solved, and
rightly or wrongly, I think I understand JavaScript much better now.

Feb 13 '06 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
1598
by: Jimmy Cerra | last post by:
I am a little confused how the memory for objects is allocated in JavaScript. David Flanagan, in "JavaScript: The Definitive Guide," states that each property of a class takes up memory space when instantiated. So space is created for aMethod three times in this example: // Example 1 function aMethod() {/*stuff*/}; function AClass() { /*stuff*/
6
22524
by: Martin | last post by:
I'd like to be able to get the name of an object instance from within a call to a method of that same object. Is this at all possible? The example below works by passing in the name of the object instance (in this case 'myDog'). Of course it would be better if I could somehow know from within write() that the name of the object instance was 'myDog' without having to pass it as a parameter. //////////////////////////////// function...
8
3188
by: Steve Neill | last post by:
Can anyone suggest how to create an arbitrary object at runtime WITHOUT using the deprecated eval() function. The eval() method works ok (see below), but is not ideal. function Client() { } Client.prototype.fullname = "John Smith"; var s = "Client"; eval("var o = new " + s + "();"); alert(o.fullname);
26
5680
by: yb | last post by:
Hi, Is there a standard for the global 'window' object in browsers? For example, it supports methods such as setInterval and clearInterval, and several others. I know that w3c standardized several parts of the DOM, but this does not include the window object. Thank you
4
1577
by: Daniel | last post by:
Hi, I was reading Douglas Crockford's article on prototypal inheritance at http://javascript.crockford.com/prototypal.html. I think it also relates to a post back in Dec 2005. The mechanism discussed was: function object(o) { function F() {} F.prototype = o; return new F();
14
2806
by: julie.siebel | last post by:
I've been wrestling with a really complex page. All the data is drawn down via SQL, the page is built via VBScript, and then controlled through javascript. It's a page for a travel company that shows all the properties, weeks available, pricing, etc. for a particular area of Europe. The data varies widely depending on the region; at times there will be 50 properties, and at other times only a half dozen. The cross referencing of...
1
2036
by: Jean-Paul Calderone | last post by:
On Tue, 22 Apr 2008 14:54:37 -0700 (PDT), yzghan@gmail.com wrote: The test doesn't demonstrate any leaks. It does demonstrate that memory usage can remain at or near peak memory usage even after the objects for which that memory was allocated are no longer live in the process. This is only a leak if peak memory goes up again each time you create any new objects. Try repeated allocations of a large dictionary and observe how memory...
11
1369
by: Are Nybakk | last post by:
Hi, I've stumbled into a problem I just can't figure out. I found out that variables in JS don't have local scope inside brackets in say, a loop, but things still doesn't add up. Also, the phenomena seemed very much alike to a closure-related one, but I'm not returning any functions as far as I can see (I'm fresh when it comes to closures tho). Let me illustrate the very basic task at hand, which is filling an array with new objects. All...
0
8680
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8609
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9169
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9030
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
8871
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
6528
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
4371
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
2
2335
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2007
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.