Skip to main content

Array magic in JavaScript

I was trying to create a queue to collect all the element related functions to run after the elements had been created. As I was Googling, I came by this snippet.
var calls = [];

function executeNext(next) {
    if(calls.length == 0) return;
    var fnc = calls.pop();
    fnc();
    if(next) {
        executeNext(true);
    }
}

/*To call method chain synchronously*/
calls.push(callMe3);
calls.push(callMe2);
calls.push(callMe1);
executeNext(true);

/*To call method chain asynchronously*/
calls.push(callMe3);
calls.push(function(){
    callMe2();
    executeNext(false);
});
calls.push(function(){
    callMe1();
    executeNext(false);
});
An array was a perfect fit with the built in push() and pop() function. I also needed something that would work the pop() till the array was empty. As Douglas Crockford says in his wonderful book 'JavaScript: the good parts', arrays are actually (slightly disguised) objects. So one can simple add to the native methods that the array variable already has simply by declaring it and then use it. This would be truly elegant and very readable.
The Html Code used
<p id="demo1">
<br>Click the button to call the new ucase() method, and display the result.</p>
<br><button onclick="myFunction()">Try it</button>
And the JavaScript used
var fruits = ["Banana1", "Orange1", "Apple1", "Mango1"]
fruits.myUcase=function()
{
for (i=0;i<this.length;i++)
  {
  this[i]=this[i].toUpperCase();
  }
}

function myFunction()
{
fruits.myUcase();
var x=document.getElementById("demo1");
x.innerHTML=fruits;
}
Demo 1:
Click the button to call the new ucase() method, and display the result.

When one declares a new array, one simply inherits a prototype- this is called prototypal inheritence. JavaScript gives us the power to change this prototype itself. Since the array is actually an object, one can simply add methods directly to the array prototype. From w3school's reference page
<p id="demo2">
Click the button to create an array, call the new lcase() method, 
<br>and display the result.</p>
<button onclick="myFunction2()">Try it</button>
And the javascript
Array.prototype.myLcase=function()
{
for (i=0;i<this.length;i++)
  {
  this[i]=this[i].toLowerCase();
  }
}

function myFunction2()
{
var fruits2 = ["BANANA2", "OrAnGe2", "APpLE2", "mANgO2"];
fruits2.myLcase();
var x=document.getElementById("demo2");
x.innerHTML=fruits2;
}
Demo 2:
Click the button to create an array, call the new lcase() method,
and display the result.

As mentioned before, since the prototype for Arrays has been changed to add a new method myLcase() to change all the elements in the array to lower-case, it should be able to use this method myLcase() in the previously declared array fruits (used in the demo1.).
function myFunction3()
{
fruits.myLcase();
var x=document.getElementById("demo");
x.innerHTML=fruits;
}
The HTML is the same as in the first Demo.
Demo 3:
Click the button to call the new lcase() method on the fruits variable
and display the result.

This means that the methods added to the Array prototype would be usable even in the case of previously declared array variables. So the way of declaration affects the scope of the method. The term Scope itself is worthy of another blog post.

Since my specific need was to create a array to which one functions would be added which would empty it one by one and use them individually as an argument to the function given as an argument to the method added to the already declared array variable. To put it more simply, f is a function given as an argument to the added method popall. While actually using this method, the argument given is alert, which means the actual function happening when f(this.pop()) is alert(this.pop()) .
      stack = []
      stack.popall=function(f){
        if(this.length == 0) return this;
        while(this.length != 0) f(this.pop());
        return this;
      };

      stack.push('ah');
      stack.push('ah1');
      stack.push('ah2');
      stack.push('ah3');
And the html-
<button onclick=alert(stack.pop())>pop</button>
<button onclick=stack.push('ah'+stack.length.toString())>push</button>
<button onclick=stack.popall(alert)>empty</button>
<button onclick=stack.popall(alert).push('empty!')>empty n push</button>
Demo:

Comments

Post a Comment

Popular posts from this blog

In the right direction, perhaps ?

i've been toying around with a PHP framework called symfony . actually i wanted to know what MVC ( Model-View-Controller ) was, and i am really comfortable with PHP, so downloaded a copy and made a sandbox on my xampp htdocs directory. after i started playing around it just hit me that how much programming has simplified over the 12 years since i wrote my "hello world" program in c. where 150 people were needed to code a simple website back then, that too in about a year, now things can be done with just one or two programmers in about a fortnight. i think thats awesome. computers are finally doing what they were invented to do - to reduce human work. one really interesting thing is the askeet tutorial. here they guide you through making a replica of their site over 24 days, with each tutorial taking not more than one and a half hours to completely understand and implement. Also the symfony site itself is created on symfony, and that's really cool. ok, what hit me

Mind and Friendships

This post seems to be ( atleast in my mind ) a long one. but before i write about the topic of the blog post, i would like to describe my opinions of connected topics which will lead to the actual post. First let us look at the growth of the mind as a graph covering fixed points, each of which are a topic of knowledge. A person's mind, at the beginning of life is like a line ( connecting 2 points, hunger and mother's breast ) which comes into existence only at some points and otherwise is simply a blank. after a few months, the lines become more permanent and stressed. after some more time, as the child grows and learns and understands more things, some more points add to this. if we imagine our mind to be the space enclosed in these points, then we would have a multidimensional graph. (think a really very weirdly shaped object.). However, the " The mind, once expanded to the dimensions of larger ideas, never returns to its original size. " - Oliver Wendell

a keeper from kiterunner

today was watching kiterunner. awesome movie. it was this dialog that hit me hard - "Now, no matter what the mullah teaches, there is only one sin, only one. And that is theft. Every other sin is a variation of theft... When you kill a man, you steal a life. You steal his wife's right to a husband, rob his children of a father. When you tell a lie, you steal someone's right to the truth. When you cheat, you steal the right to fairness... There is no act more wretched than stealing, Amir."