JavaScript is a fully-featured Object-Oriented programming language. On the surface, it shares syntactical similarities with Java and C, but the mentality is quite different. At its core, JavaScript is more similar to functional languages. Inside is a list of JavaScript tips, some offer techniques to simulate features found in C-like languages (such as assertions or static variables). Others are meant to improve performance and explore some of the more obscure parts of the web scripting language.
Arrays as Multipurpose Data Structures
Although that JavaScript may seem limited on the data structure front at first glance, its Array class is much more versatile than the usual array type found in other programming languages (like C++ or Java). It's commonly used as an array or associative array, and this tip demonstrates how to use it as a stack, queue, and binary tree. Re-using the Array class instead of writing such data structures provides two benefits: First, time isn't wasted rewriting existing functionality, and second, the built-in browser implementation will be more efficient than its JavaScript counterpart.
Stack
A stack follows the Last-In First-Out (LIFO) paradigm: an item added last will be removed first. The Array class has 2 methods that provide stack functionality. they are push() and pop(). push() appends an item to the end of the array, and pop() removes and returns the last item in the array. The next code block demonstrates how to utilize each of them:
var stack = []; stack.push(2); // stack is now [2] stack.push(5); // stack is now [2, 5] var i = stack.pop(); // stack is now [2] alert(i); // displays 5
Queue
A queue follows the First-In First-Out (FIFO) paradigm: the first item added will be the first item removed. An array can be turned into a queue by using the push() and shift() methods. push() inserts the passed argument at the end of the array, and shift() removes and returns the first item. Let's see how to use them:
var queue = []; queue.push(2); // queue is now [2] queue.push(5); // queue is now [2, 5] var i = queue.shift(); // queue is now [5] alert(i); // displays 2
It's worth noting that Array also has a function named unshift(). This function adds the passed item to the beginning of an array. So a stack can also be simulated by using unshift()/shift(), and a queue can be simulated by using unshift()/pop().
If all these function names are confusing, you may create aliases with your own names. For example, to create a queue with methods named add and remove:
var queue = []; queue.add = queue.push; queue.remove = queue.shift; queue.add(1); var i = queue.remove(); alert(i);
Binary Tree
A binary tree represents data in a tree of nodes. Each node has a value and two children (left and right). In C, this data structure is usually implemented using structures and pointers. This implementation is possible to do in JavaScript using objects and references; however, for smaller trees, there is an easier and quicker way using only one array. The first item of the array will be the head of the tree. Indexes of left and right child nodes if node i can be calculated using the following formula:
leftChild(i) = 2i + 1 rightChild(i) = 2i + 2
This image illustrates the method (courtesy of Wikipedia):

As you see, this method isn't exclusive to JavaScript, but it can be very useful when dealing with small trees. You can, for example, write your own helper functions for getting and setting a node's value or children, and traversing the tree, and those methods will be as simple as doing arithmetic calculations and/or for loops. On the other hand, the disadvantage of this method is that wasted space grows as the depth of the tree increases.
String Concatenation vs. Array.join
This cannot be stressed enough, doing many string concatenation operations can be a major hit on performance, and it's easy to avoid in many situations. Consider for example that you want to build a string out of many pieces, one bad way to do this is using the + to concatenate all pieces into a huge string, one piece at a time:
str = ''; for (/* each piece */) { str += piece; // bad for performance! } return str;
This method will result in too many intermediate strings and concatenation operations, and will poorly perform overall.
A better approach to this problem is using Array.join(), this method joins all array elements into one string:
var tmp = []; for (/* each piece */) { tmp.push(piece); } str = tmp.join(''); // Specified an empty separator, thanks Jonathan return str;
This method doesn't suffer from the extra string objects, and generally executes faster.
Binding Methods to Objects
Anyone who works with JavaScript events may have come across a situation in which they need to assign an object's method to an event handler. The problem here is that event handlers are called in the context of their HTML element, even if they were originally bound to another object. To overcome this, I use a function that binds a method to an object; it takes an object and method, and returns a function that always calls the method in the context of that object. I found the trick in Prototype, and wrote the following function to use it in projects that don't include Prototype:
function bind(obj, method) { return function() { return method.apply(obj, arguments); } }
And this snippet shows how to use the function:
var obj = { msg: 'Name is', buildMessage: function (name) { return this.msg + ' ' + name; } } alert(obj.buildMessage('John')); // displays: Name is John f = obj.buildMessage; alert(f('Smith')); // displays: undefined Smith g = bind(obj, obj.buildMessage); alert(g('Smith')); // displays: Name is Smith
Sorting With a Custom Comparison Function
Sorting is a common task. JavaScript provides a method for sorting arrays. However, the method sorts in alphabetical order by default. Non-string elements are converted to strings before sorting, which leads to unexpected results when working with numbers:
var list = [5, 10, 2, 1]; list.sort() // list is now: [1, 10, 2, 5]
The explanation of this behavior is simple: Numbers are converted to strings before sorting them, so 10 becomes '10' and 2 becomes '2'. The JavaScript interpreter compares two strings by comparing the first two characters of each: str1 is considered "less than" str2 if str1's first character comes before str2's first character in the character set. In our case, '1' comes before '2' so '10' is less than '2'.
Fortunately, JavaScript provides a way to override this behavior by letting us supply a comparison function. This function defines how elements are sorted, it takes two compared elements a and b as parameters, and should return:
- A value less than zero if a < b.
- zero if a == b.
- A value greater than zero if a > b.
Programming such a function for number comparison is trivial:
function cmp(a, b) { return a - b; }
Now we can sort our array using this function:
var list = [5, 10, 2, 1]; list.sort(cmp); // list is now: [1, 2, 5, 10]
This flexibility in Array.sort() allows for more sophisticated sorting. Let's say you have an array of forum posts, each post looks something like:
var post = { id: 1, author: '...', title: '...', body: '...' }
If you want to sort the array by post id's, create the following comparison function:
function postCmp(a, b) { return a.id - b.id; }
It's reasonable to say that sorting using a native browser method is going to be more efficient than implementing a sort function in JavaScript. Of course, data should be sorted server-side if possible, so this shouldn't be used unless absolutely necessary (for example, when you want to offer more than one sort order on one page, and do the sorting in JavaScript).
Assertion
Assertion is one of the commonly-used debugging techniques. It's used to ensure that an expression evaluates to true during execution. if the expression evaluates to false, this indicates a possible bug in code. JavaScript lacks a built-in assert function, but fortunately it's easy to write one. The following implementation throws an exception of type AssertException if the passed expression evaluates to false:
function AssertException(message) { this.message = message; } AssertException.prototype.toString = function () { return 'AssertException: ' + this.message; } function assert(exp, message) { if (!exp) { throw new AssertException(message); } }
Throwing an exception on its own isn't very useful, but when combined with a helpful error message or a debugging tool, you can detect the problematic assertion. You may also check whether an exception is an assertion exception by using the following snippet:
try { // ... } catch (e) { if (e instanceof AssertException) { // ... } }
This function can be used in a way similar to C or Java:
assert(obj != null, 'Object is null');
If obj happens to be null, the following message will be printed in the JavaScript console in Firefox:
uncaught exception: AssertException: Object is null
Static Local Variables
Some languages like C++ support the concept of static variables; they are local variables that retain their values between function calls. JavaScript doesn't have a static keyword or direct support for this technique. However, the fact that functions are also objects makes simulating this feature possible. The idea is storing the static variable as a property of the function. Suppose that we want to create a counter function, here is a code snippet that shows this technique in action:
function count() { if (typeof count.i == 'undefined') { count.i = 0; } return count.i++; }
When count is called for the first time, count.i is undefined, so the if condition is true and count.i is set to 0. Because we are storing the variable as a property, it's going to retain its value between function calls, thus it can be considered a static variable.
We can introduce a slight performance improvement to the above function by removing that if check and initialize count.i after defining the function:
function count() { return count.i++; } count.i = 0;
While the first example encapsulates all of count's logic in its body, the second example is more efficient. The choice is up to you.
null, undefined, and delete
JavaScript is difference from other programming languages by having both undefined and null values, which may cause confusion for newcomers. null is a special value that means "no value". null is usually thought of as a special object because typeof null returns 'object'.
On the other hand, undefined means that the variable has not been declared, or has been declared but not given a value yet. Both of the following snippets display 'undefined':
// i is not declared anywhere in code alert(typeof i); var i; alert(typeof i);
Although that null and undefined are two different types, the == (equality) operator considers them equal, but the === (identity) operator doesn't.
JavaScript also has a delete operator that "undefines" an object a property (thanks zproxy), it can be handy in certain situations, you can apply it to object properties and array members, variables declared with var cannot be deleted, but implicitly declared variables can be:
var obj = { val: 'Some string' } alert(obj.val); // displays 'Some string' delete obj.val; alert(obj.val); // displays 'undefined'
Deep Nesting of Objects
If you need to do multiple operations on a deeply nested object, it's better to store a reference to it in a temporary variable instead of dereferencing it each time. For example, suppose that you want to do a series of operations on a textfield accessible by the following construct:
document.forms[0].elements[0]
It's recommended that you store a reference to the textfield in a variable, and use this variable instead of the above construct:
var field = document.forms[0].elements[0]; // Use field in loop
Each dot results in an operation to retrieve a property, in a loop, these operations do add up, so it's better to do it once, store the object in a variable, and re-use it.
Using Firebug
Firefox has a fabulous extension for debugging JavaScript code called Firebug. It offers an object inspector, a debugger with breakpoints and stack views, and a JavaScript console. It can also monitor Ajax requests. Moreover, the extension provides a set of JavaScript functions and objects to simplify debugging. You may explore them in detail at Firebug's documentation page. Here are some that I find most useful:
$ and $$
Those familiar with Prototype will immediately recognize these two functions.
$() takes a string parameter and returns the DOM element whose id is the passed string.
$('nav') // returns the element whose id is #nav.
$$() returns an array of DOM elements that satisfy the passed CSS selector.
$$('div li.menu') // returns an array of li elements that are // located inside a div and has the .menu class
console.log(format, obj1, ...)
The console object provides methods for displaying log messages in the console. It's more flexible than calling alert. The console.log() method is similar to C's printf. It takes a formatting string and optional additional parameters, and outputs the formatted string to the console:
var i = 1; console.log('i value is %d', i); // prints: // i value is 3
console.trace()
This method prints a stack trace where it's called. It doesn't have any parameters.
inspect(obj)
This function takes one parameter. It switches to the inspection tab and inspects the passed object.












Comments
zproxy
instead of using console one can use firefox
window.dump(<string>)</string>method.also delete is for removing a member of a type.
you can also do
<expr> = void(0)</expr>, which also sets a variable to undefined state.I did not understand the binary tree section. maybe you can clarify.
cheers
Posted at 9:02 a.m. on October 8, 2006
Ayman Hourieh
Hi,
Thanks for your feedback. Regarding delete, while I did mention that it removes properties, the opening sentence is ambiguous. I've correct it. Thanks.
As for binary trees, I'll try to clarify the concept briefly. Suppose that you have the following tree:
ais the head of the tree. Therefore, we will store it at the beginning of the array:bandcare children ofa, anda's index is 0. According to the formulas I posted:So
bwill be stored at index 1. Forc, we will do the same thing, but use the right child formula:Our array now looks like:
Now let's see where to store
c's children:And the array becomes:
Notice how there are 2 undefined positions in the array. If
bhad children, they would be stored there.Hope this clears things up.
Posted at 4:58 p.m. on October 8, 2006
Anonymous
Hi:
These is great information you are sharing.
Thanks,
Posted at 6:59 p.m. on October 8, 2006
Anonymous
Good info, thanks!
Posted at 7:25 p.m. on October 8, 2006
Anonymous
Excellent tips and a very useful website! Dugg and submitted this article at howtohut http://www.howtohut.com/9_javascript_tips_you_may_not_know
Posted at 9:30 p.m. on October 8, 2006
Mike Atlas
You neglected one of the most fundamentally important things about JavaScript that most people do not know:
It treats functions as first class values.
In other words, you can do great things like this in JavaScript:
Posted at 12:14 a.m. on October 9, 2006
Ayman Hourieh
I didn't neglect it. I assumed that the reader was aware of this feature. It's used in tip #1 in which a synonym for push is created, and in #3 in which the returned bound function is an anonymous function.
Posted at 1:41 a.m. on October 9, 2006
Alok
This is a real good and informative article. I have started working in javascript for last few months. I am getting more and more impressed by its little tricks and dynamicity of the language. Awesome work. Thanks
Posted at 2:50 a.m. on October 9, 2006
leo
For the counter example, an immediate function application returning a function is a common and clear pattern when constructing functions with local state:
functionFoo = (function () { var counter = 0; return function () { return counter++; }; })();
Two syntactic forms I would mention are:
Instead of
var x; if (test) { x = branch1; } else { x = branch2; }
do
var x = test ? branch1 : branch2;
when not using the above function application with a stateful function return, a light version would be something like
someFunction((y+=4, x+=y), z) being shorthand for
y+=4 x+=y someFunction(x,z)
Leo
Leo
Posted at 4:56 a.m. on October 9, 2006
Anonymous
Useful info, thanks!
Posted at 11:02 a.m. on October 9, 2006
Tim
THANKS for the custom sort function, it's sooo useful ! thanks !
Posted at 12:30 p.m. on October 9, 2006
rsr
May I know if javascript can read and write to a local disc file?
Posted at 4:55 p.m. on October 9, 2006
Ayman Hourieh
In short, no. JavaScript is not allowed to read or write to the local file system for security reasons. Use cookies for local storage.
However, some browsers allow sufficiently-privileged scripts to access the local file system. For example, Mozilla browsers allow installed extensions to access local files. Check this page for some code samples.
Posted at 6:08 p.m. on October 9, 2006
SAAL
is everything above compatible with most browsers? I mean, is there anything here olny compatible with curring edge JS processors?
Posted at 2:44 p.m. on October 10, 2006
Ayman Hourieh
Yeah, except for the last one (Firebug, which is obviously Firefox-only), all tips should be compatible with modern browsers (Gecko based, IE 5.5+, KHTML, Opera).
Posted at 6:50 p.m. on October 10, 2006
Jonathan
I tried your Array.join technique for string concatenation, but it adds a comma between every part of the array. Like,this,you,know,what,I,mean?
Posted at 3:22 p.m. on October 11, 2006
Jonathan
ah I found the answer.. you need to use var.join("") instead of var.join()
Posted at 3:29 p.m. on October 11, 2006
Jonathan
I did a little more investigation into this, and the technique as described on http://www.comet.co.il/en/articles/performance/article.html is alot faster..
it uses buffer[buffer.length] = "somedata" instead of buffer.push("somedate")
in my tests it's about 20 times as fast..
Posted at 3:39 p.m. on October 11, 2006
Ayman Hourieh
Interesting observation. What browser(s) did you test with?
Posted at 10:04 p.m. on October 11, 2006
Gr
IE 6 and FF 1.5B1
Posted at 9:10 a.m. on October 12, 2006
Ayman Hourieh
Tested with Firefox and looks like
array[array.length] = valis indeed faster thanarray.push(val). Interesting. Thanks Jonathan and Gr!Posted at 4:54 p.m. on October 12, 2006
Anonymous
IE5 (or more accurately, JScript 5.0) did not have support for Array.push among a number of other things like the call or apply methods. Also interesting to note is that Microsoft still considers IE5.0 a supported browser (because of the support window for Windows 2000 for which IE5 was the default browser) whereas Microsoft has discontinued support for IE5.5. Somewhat moot as nobody should really be using either of them.
Posted at 2:30 a.m. on October 15, 2006
Wes
Tested the following on FF2.0 (Mac G4 1.25 GHz ) and concat was 3x faster. Unless my test is flawed somehow (please tell me!).
Posted at 2:22 a.m. on October 29, 2006
Wes
OK, concat() may cause trouble because it's the name of a String object method, though it shouldn't. Regardless, I tested again on a Windows machine, faster than my Mac, and had to increase the number of iterations to 8000 to get decent results. The results were wildly inconsistent in both FF2 and IE7, but on average using the concat is generally a bit faster in FF, but slower in IE. So I guess it depends which browser you want to optimize for. But how often do you need to build a string that large? And we're talking about differences of milliseconds -- It really makes very little difference practically, as far as I can tell.
Posted at 3:40 p.m. on October 31, 2006
Ayman Hourieh
Hi,
I remember running into similar results when I conducted my tests. I think that this test doesn't reflect real situations in which one needs to concatenate a large number of strings for two reasons:
s) is not returned or used anywhere in the function. I think that Firefox optimizes away theforloop, which results in great improvements to performance. Try to makesa global variable for example, and see how it goes. If I recall correctly, results changed dramatically in my tests after this modification."string"with"string" + i(For example).Thanks for your feedback, and I hope that my reply sheds some light on the issue.
Posted at 5:02 p.m. on November 1, 2006
Tommy
about:blank
Posted at 7:35 p.m. on December 6, 2006
Bill Burdick
Since you can't use objects as keys in Javascript's associative arrays (keys are converted to strings, like "[object Object]"), here is a trick you can use to implement sets:
You can use
getId(obj)to get a unique key for each of your objects that you want to store in sets (kind of likehashCode()in Java).To store an object in a set:
set[getid(obj)] = obj;to test if the object is in the set:
if (getId(obj) in set) {...}to remove an object from a set:
delete set[getId(obj)]Bill Burdick
Posted at 11:15 p.m. on January 16, 2007
Subodh
how to implement tree (not binary one)
give complete information how to implement tree(e.g. windows explorer tree) and also give method to traverse tree effectively, method to select particular node and how to put in memory tree in visual effect
Posted at 5:48 a.m. on February 28, 2007
javed
i have many difficulties to learn javascript sir i have no understanding about its function therefore i am not able to a good scripting. sir plz can u help me in this case?
Posted at 7:58 a.m. on May 8, 2007
Anonymous
It is misleading to say that "==" considers null and undefined equal. undefined is not a value, it is the absence of a value, whereas null is a value that is interpreted to mean nothing. The difference?
var null = "hello world"; // error alert(null);
var undefined = "goodbye cruel world"; alert(undefined); // "goodbye cruel world"
"undefined" is essentially what an empty variable is represented as when asked for a string representation.
Posted at 7:45 p.m. on August 18, 2008
Michael S.
Can you use arguments.callee to avoid having to repeat the name of the function in the body of the function? "return arguments.callee.i++", etc.
Posted at 9:25 p.m. on August 18, 2008
Frank Watts
Best tip anyone ever gave me was to just Disable Javascript and that has worked for years!
FW http://useurl.us/12m
Posted at 3:52 a.m. on August 19, 2008
grillonbleu
When i see all these trendy $ functions i wonder whatever happened to meaningful function names. Two popular libraries that i know of (and probably more i am not aware of) define $. If i am not developping something trivially small, i prefer to avoid any future name clash by just avoiding these shorthands and use the full function name instead (jQuery(...), etc.). Furthermore, it is clearer for any future maintainer.
Posted at 5:01 a.m. on August 19, 2008
Nick
You can more transparently achieve the same thing by implementing toString() for the objects you'd like to use as keys.
Posted at 2:33 p.m. on August 19, 2008
Anonymous
That is not an example of first-class functions, anyway: you're just calling the
alert()function with the result of evaluating theaverageOfTwo(1, 3)function. Any reasonable language supports that; what is slightly less common is the ability to treat functions as first-class values.Posted at 4:53 p.m. on August 19, 2008
Anonymous
Also worthy of note is that one can obtain the updated script engine for their ancient 5.x browser as a separate install.
Posted at 10:16 p.m. on August 21, 2008
Bernhard
Arrays also make great containers for static data that can then be used by auto-write scripts. See this little handrolled example.
Posted at 5:57 p.m. on August 23, 2008
Anonymous
there's also an obvious problem with your test, namely, the thread that firefox spawns to perform the javascript interpretation of your test code is at the mercy of the scheduling algorithm and the amount of applications running concurrently on the machine you are testing with because you are relying on time of the current date rather than how many cpu clock cycles are spun during your specific test. Google "understanding how an operating system works" for more information.
Posted at 12:01 a.m. on September 15, 2008
Ricardo
Been a long time, huh?
In your 'static local variables' example, the 'i' property is not local. It's globally accessible through count.i for any function running in the same window.
Something like
function count() { this.count = function(){ return ++i }; return i=0; }
makes more sense. The 'i' var is only retained inside the inner function's closure, and it's not accessible in any other way than by calling the count function itself. You can get a small performance increase by the use of pre-increment also.
Posted at 9:23 p.m. on October 8, 2008
Ricardo
You can avoid conflicts between libraries and still use the $ function.
Posted at 9:25 p.m. on October 8, 2008
_es
with({counter:0}) var functionFoo2 = function(){return counter++;};Posted at 5:33 a.m. on January 28, 2009
_es
var count1 = function(){var n = 0; return function(){return n++;};}(); with({n:0})var count2 = function(){return n++;};
Posted at 7 a.m. on January 28, 2009
Mostafa Farghaly
Great article ayman , i reach it from google searching for queue and stacks while i was writing one on my blog .
Posted at 4:15 p.m. on March 3, 2009
Palanisamy
Excellent post . Keep up the good work.
Posted at 9:28 a.m. on March 24, 2009
Anonymous
Nice explanation. Just from your explanation, it's easy to derive a binary tree class, complete with manipulation methods (e.g.: add, remove, get, find, etc.). The math is simple and constant.
Thanks Michael
Posted at 3:57 a.m. on September 19, 2009
Anonymous
It's not that JavaScript, per se, is not allowed to read/write to and from the local file system; rather, it's the JavaScript runtime_engine that disallows it. If you wanted to, you could hack Mozilla so as to link extra (non-standard) JS methods to low-level filesystem-handling code. Then you could call a File.open(...) JS method and it would get dispatched internally to custom file-handling methods (presumably C or C++ on most platforms; maybe Obj. C under OS X).
Of course, it would never gain widespread adoption for security reasons.
Michael
Posted at 4:07 a.m. on September 19, 2009
Brent
Stumbled on this during a google journey...
Great post. Thanks a bunch for the great read!
Posted at 5:29 p.m. on September 27, 2009
Daniele
A good recap of some important features of Javascript, thanks! Apart from that, good luck with Dublin weather! :)
Posted at 10:07 a.m. on October 6, 2009
Moe
It's weird, but upon reading the first several, all I could think about was Perl. I'm already familiar with push/pop/shift/unshift/join/etc. because it has all of those, too.
Posted at 8:41 a.m. on May 6, 2010
Thor Larholm
Your example with static local variables exposes i as a public property on the function object.
This can be undesirable if you want to encapsulate your logic and prevent outside tampering of i.
You can solve this with a closure.
On the first invocation, count will be changed into a new function that has a private variable i in its function closure scope.
If you look at count.toString() after the first invocation you will see that it now contains the following code:
Posted at 8:54 a.m. on May 6, 2010
gasper_k
About null, undefined, and delete: you can't delete a property that exists in the window object in IE. See here for more detail.
Posted at 10:52 a.m. on May 6, 2010
steve
Thank you, some hadn't heard about in there
Posted at 2:02 p.m. on May 6, 2010
Adam
Re: Sorting With a Custom Comparison Function
function cmp(a, b) { return a - b; }
In Java, it will lead to IntegerOverflow in extreme case. Never tried in javascript though.
Posted at 2:14 p.m. on May 6, 2010
Michael Paul
Something very important that you need to know is how to handle the scope. The wrong way:
This example will cause an error because the anonymous function will be called from window scope. And the right way to do it:
Posted at 2:24 p.m. on May 6, 2010
random
count() has generated a few comments. Aesthetically, I prefer _es' version of, or the following if with is not available:
Of course, for this specific problem I'd use:
but that's showing off first class functions, not private variables :-). Thor's example is an interesting demo of a function replacing itself when called, but I can't think of a mind-bending yet not evil reason to do that.
Posted at 3:45 p.m. on May 6, 2010
random
Also, Michael's comment is important .. and an instance of when bind() is useful. If I'm not mistaken usage would be:
Mention could also be made of avoiding reference cycles and letting the collector free more memory, but I think that's out of scope here.
Posted at 3:55 p.m. on May 6, 2010
Rajan
Innovative information about "Binding Methods to Objects". Thanks for Sharing.
Posted at 6:32 a.m. on June 8, 2010
Pacifik
Very grt info..& useful 1 thnks
Posted at 9:53 a.m. on June 30, 2010
Nope
Um it's not OOP, from the very first sentence you are wrong.
Posted at 5:10 p.m. on June 17, 2011
Robert
Ummm - yes it is. But the OOP syntax is fundamentally different from most other languages that you will see....
And thanks for the article!
Posted at 11:37 p.m. on June 18, 2011
ujjaini
I have been looking for a post of this kind for so long..... You have explained very well with minimal code Thx a lot !
Posted at 8:53 p.m. on July 19, 2011
Gouri
Static Local Variables thing didn't work for me!
Posted at 12:28 p.m. on August 26, 2011
very
Hey, that's still a very nice article. Except that static local variables part of course. :D Heh! But apparently there are several opinions about that topic.
What I'd like to ask is about the "wasted space" with deep binary trees. What do you mean with wasted? As far as I know JavaScript arrays usually are sparse arrays. This means that undefined elements do not necessarily consume memory, so the allocated memory is about linearly dependend on the number of defined elements. And even if there is some extra memory allocated for unused elements, I think using an array would probably consume less memory than any other implementation (for example linked objects). Maybe even if the tree degenerates into a linked list. But that's just a guess and it probably depends heavily on the internal implementation of the array.
Anyhow array indices are currently 32-bit unsigned (will it ever change?) so the maximum depth of the binary tree is 32 (or 31 if you start counting at 0) with the rightmost node being stored at index
11111111111111111111111111111110band maybe an additional leftmost node at depth 33. So it's probably better to use linked objects (or linked arrays) anyway.Posted at 1:41 a.m. on September 1, 2011