Software Secret Weapons™  
Javascript Closures posted by Pavel Simakov on 2006-03-24 00:00:20 under AJAX
view comments
 


A function that references an outer lexically scoped variable is called a closure. I have discovered a good example of using closures in JavaScript.

This all started with a HTML page that contained Flash plug-in. Plug-in talks to a web server and tells the page when something interesting has happened on the server. Flash can talk to HTML page by executing JavaScript function call. For example, when new data packet is available from the server, plug-in executes following JavaScript code, passing in data from server:


javascript: acceptDataFromServer("data data data data more data other data a bytes");

Main page would perform some processing using this data. It might show or hide some portions of page, replace some images, etc.

But what if a page has not loaded yet, but a plug-in has already received new data from the server? What if page has not been fully received and rendered? What if page DOM model has not been completed? What if the last portions of HTML have not arrived from the server yet? What if a portion of HTML that contains plug-in is already here; it is rendered, plug-in has received the data from server, calls the function... Boom!

This is the time to use a closure. One can use closure to capture a call from plug-in and delay it until the moment the page loads completely. Notice how we declare anonymous function inside "acceptDataFromServer" and how we pass into it a "data" variable. This is a closure - an inner anonymous function new function(){...} that keeps a reference to the variable from outer scope data.

  • Declare this portion of JavaScript anywhere on the page, but above the declaration for Flash plug-in:

<script language="JavaScript"><!--

var pageCompleted = false;
var dataFromServerClosure = null;

function acceptDataFromServer(data){
  dataFromServerClosure = new function(){
    receiveDataFromServerNow(data);
  }
  receiveDataFromServer();
}


function receiveDataFromServer(){
  if (pageComplete){
    if (dataFromServerClosure){
      dataFromServerClosure();
      dataFromServerClosure = null;
    }  
  }
}

function readyToReceiveDataFromServer(){
  pageCompleted = true;
  receiveDataFromServer();
}

--></script>

  • Delcare another portion of JavaScript at the very end of the page, below all the objects that will be manipulated when server data arrives:

<script language="JavaScript"><!--
  readyToReceiveDataFromServer();
--></script>

Comment (1)

  • Comment by Anatoliy Klimenko — August 5, 2008 @ 10:07 am

    Not useful, poorly written with mistakes (for example, variable pageComplete is not declared and assigned anywhere).


Leave a comment


  Copyright © 2004-2007 by Pavel Simakov SourceForge.net Logo