SitePoint Sponsor

User Tag List

Results 1 to 15 of 15
  1. #1
    SitePoint Addict Jack Matier's Avatar
    Join Date
    Feb 2005
    Posts
    292
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Simple Request/Send Ajax function.

    I'm stuck and frustrated at this at the moment. I've tried having my icecream, listening to my music and taking a walk around the neighborhood and none of these things have worked out.

    Although I'm just starting with Ajax I want to make it simpler for myself. I notice that I would be performing a lot of the same thing over and over again, and the idea of writing that over and over and over again is really frustrating when it seems that I could do it in one line. So what I want in a nutshell is.

    Code:
    function ajaxQuery(url) { 
        // Send Request, Return Bling.
    }
    
    var usefulVar=ajaxQuery(url);
    The code I've been working with is this.

    Code:
    function ajaxQuery(url) {
    	function stateChanged() { 
    		if (xmlHttp.readyState==4 || xmlHttp.readyState=="complete") {
    			// The Magical Value..... I want to move THIS
    			xmlHttp.responseText;
    		}
    	}
    
    	xmlHttp=GetXmlHttpObject(stateChanged)
    	xmlHttp.open("GET",url,true) 
    	xmlHttp.send(null) 
    }
    
    // Over to here :)
    var yippie=ajaxQuery('url')
    I can alert it from there and I can assign it to a variable (though not a global variable?), but I can't seem to return it from inside of two functions.

    In case you want it.. GetXmlHttpObject() is.. and just returns the state.
    Code:
    function GetXmlHttpObject(handler) { 
    	var objXmlHttp=null
    	
    	if (navigator.userAgent.indexOf("Opera")>=0) {
    		alert("Not currently working for Opera.. I'll have to grab this later... because AJAX can work in opera 7+ I hear...");
    		return 
    	}
    	if (navigator.userAgent.indexOf("MSIE")>=0)	{ 
    		var strName="Msxml2.XMLHTTP"
    		if (navigator.appVersion.indexOf("MSIE 5.5")>=0) {
    			strName="Microsoft.XMLHTTP"
    		} try { 
    			objXmlHttp=new ActiveXObject(strName)
    			objXmlHttp.onreadystatechange=handler 
    			return objXmlHttp
    		} catch(e) { 
    			alert("Error. Scripting for ActiveX might be disabled");
    			return 
    		}
    	} 
    	if (navigator.userAgent.indexOf("Mozilla")>=0) {
    		objXmlHttp=new XMLHttpRequest()
    		objXmlHttp.onload=handler
    		objXmlHttp.onerror=handler 
    		return objXmlHttp
    	}
    }

  2. #2
    SitePoint Evangelist pip's Avatar
    Join Date
    Jun 2001
    Location
    Cape Town, South Africa
    Posts
    548
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Here's my JavaScript Class which I've created to make my AJAX life a little easier. It's very personalised to our systems though, so it needs tweaking... I'm still working on it and it's far from ready and complete, but maybe this would help you.

    If you plan on making use of any of these functions and/or the entire class, please tweak it to your requirements, and remove all the copyrights and notices... it's currently used in my organisation who'll have a fit if our code is used elsewhere.

    I'm sure you just need an idea of what's been done though, and I'm sure you'll probably do it differently.... so if it will help, feel free to code it in a similar way.

    To make a request, I do something like this:
    PHP Code:
    var oDNSServer = new MHG_AJAX("monitorRequest.php","GET","?Function=DNSServer&HostName=emed.mhg.lan","processFunction_DNSServer");
    oDNSServer.processRequest(); 
    I'm sure you'll understand my theroy behind it, but if you get stuck, give me a shout.

    PHP Code:
    /* -- MHG_AJAX: MHG Asynchronous JavaScript and XML -----------------------------------------------------------
    * Filename: MHG_AJAX.js
    * Version: 0.1
    * Author: Quintin Stoltz (qstoltz at mhg dot co dot za)
    * Date Created: 2005-11-07
    * Last Modified: 2006-02-08
    * Copyright (c) 2006. Metropolitan Health Group. All Rights Reserved.
    * http://www.mhg.co.za/
    *-------------------------------------------------------------------------------------------------------------
    * Description:
    * This JavaScript class defines and creates an XMLHttpRequest Object, used to submit and retrieve data from
    * a server asynchronously, allowing the developer to use common DOM libraries to manipulate a page's content
    * dynamically, depending on the result from the request. This functionality eliminates the requirement to
    * refresh a web application in order to process given data to the server.
    *-------------------------------------------------------------------------------------------------------------
    */
    function MHG_AJAX(sURL,sRequestMethod,sPostData,sCallMethod) {
    /*
    * Pre-defined Variables:
    * - oXMLHttpRequest: The object that will be used to post data to and retrieve data from.
    * - sURL: The URL of the server-side application that will be processing the request.
    * - sMethod: The method of data that will be used during a request. (GET, POST, PUT, HEAD - Go to: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html for detailed information)
    */
    var oXMLHttpRequest false;
     
    this.requestURL sURL;
    this.requestMethod sRequestMethod;
    this.postData sPostData;
    this.callMethod sCallMethod;
    var 
    ssRequestURL "";
    var 
    ssRequestMethod "";
    var 
    ssPostData "";
    var 
    ssCallMethod "";
     
    //var sURL = "";
    //var sRequestMethod = "";
    //var sPostData = "";
    //var sCallMethod = "";
     
    var oResponseXML "";
    var 
    sResponseText "";
     
    var 
    aAlertUsers = new Array("QSTOLTZ","AFRYLINCK");
     
    /*
    * Create the XMLHttpRequest Object
    * The function below creates an XMLHttpRequest object for all major browsers,
    * making the use of it's functionality cross-browser complaint.
    */
    this.initializeXMLHttpRequest initializeXMLHttpRequest;
    function 
    initializeXMLHttpRequest() {
    try { 
    oXMLHttpRequest = new ActiveXObject("MSXML2.XMLHTTP"); }
    catch(
    e) {
    try { 
    oXMLHttpRequest = new ActiveXObject("Microsoft.XMLHTTP"); }
    catch(
    e) { oXMLHttpRequest false; }
    }
    if (!
    oXMLHttpRequest && typeof(XMLHttpRequest) != "undefined") {
    try { 
    oXMLHttpRequest = new XMLHttpRequest(); }
    catch(
    e) { oXMLHttpRequest false; }
    }
    if (!
    oXMLHttpRequest && window.createRequest) {
    try { 
    oXMLHttpRequest window.createRequest(); }
    catch(
    e) { oXMLHttpRequest false; }
    }
    if (!
    oXMLHttpRequest) {
    if (
    sUsrNme && in_array(sUsrNme,aAlertUsers,true) != -1alert("Your web browser does not support the use of the XMLHttpRequest Objcet.\n\nPlease download an updated version of your browser.");
    }
    }
     
    /*
    * Make a Request
    */
    this.loadXMLDoc processXMLHttpRequest;
    this.processRequest processXMLHttpRequest;
    this.processXMLHttpRequest processXMLHttpRequest;
    function 
    processXMLHttpRequest() {
    initializeXMLHttpRequest();
    if (
    oXMLHttpRequest) {
    sRequestMethod this.requestMethod;
    sURL this.requestURL;
    sPostData this.postData;
    sCallMethod this.callMethod;
    if (
    sRequestMethod && sURL) {
        
    ssRequestURL sURL;
        
    ssRequestMethod sRequestMethod;
        
    ssPostData sPostData;
        
    ssCallMethod sCallMethod;
        
    oXMLHttpRequest.onreadystatechange processXMLHttpRequestChange;
        
    this.readyState oXMLHttpRequest.readyState;
        switch(
    sRequestMethod) {
         case 
    "POST": {
         
    oXMLHttpRequest.open(sRequestMethod,sURL,true);
         if (
    sPostData) {
         
    oXMLHttpRequest.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
         
    oXMLHttpRequest.send(sPostData);
         } else {
         if (
    sUsrNme && in_array(sUsrNme,aAlertUsers,true) != -1alert("MHG_AJAX:\nNo POST data specified. Script Aborted!");
         return;
         }
         }
         break;
     
         case 
    "PUT":
         case 
    "HEAD":
         case 
    "GET": {
         if (
    ssPostData != "") {
         
    sURL += ssPostData;
         }
         
    oXMLHttpRequest.open(sRequestMethod,sURL,true);
         
    oXMLHttpRequest.send(null);
         }
         break;
     
         default: return;
         break;
        }
    } else {
        if (!
    sRequestMethod) {
         if (
    sUsrNme && in_array(sUsrNme,aAlertUsers,true) != -1alert("MHG_AJAX:\nNo request method specified. Script Aborted!");
        } else if (!
    sURL) {
         if (
    sUsrNme && in_array(sUsrNme,aAlertUsers,true) != -1alert("MHG_AJAX:\nNo request URL specified. Script Aborted!");
        }
        return;
    }
    }
    }
     
    /*
    * XMLHttpRequest ReadyStateChange event handler
    */
    this.processXMLHttpRequestChange processXMLHttpRequestChange;
    this.processChange processXMLHttpRequestChange;
    function 
    processXMLHttpRequestChange() {
    if (
    oXMLHttpRequest) {
    if (
    oXMLHttpRequest.readyState == 4) {
        if (
    oXMLHttpRequest.status == 200) {
         
    oResponseXML oXMLHttpRequest.responseXML;
         
    sResponseText oXMLHttpRequest.responseText;
         var 
    oRootNode oResponseXML.documentElement;
         if (
    oRootNode) {
         eval(
    sCallMethod "(oResponseXML,sResponseText)");
         } else {
         if (
    sUsrNme && in_array(sUsrNme,aAlertUsers,true) != -1alert("MHG_AJAX:\n\nThere was a problem processing XML Data\n\nBlob:\n" sResponseText);
         }
        } else {
         
    sPostData "Status=" + (oXMLHttpRequest.status).toString();
         
    sPostData += "&StatusText=" encodeURI(oXMLHttpRequest.statusText);
         
    sPostData += "&RequestURL=" encodeURI(ssRequestURL);
         
    sPostData += "&RequestMethod=" encodeURI(ssRequestMethod);
         var 
    re = /&/g;
         
    sPostData += "&PostData=" encodeURI(ssPostData).replace(re,"#");
         
    sPostData += "&CallMethod=" encodeURI(ssCallMethod.toString());
         
    processError(sPostData);
        }
    }
    }
    }
     
    function 
    processError(sPostData) {
    initializeXMLHttpRequest();
    if (
    oXMLHttpRequest) {
    sPostData sPostData;
    oXMLHttpRequest.onreadystatechange processErrorChange;
    oXMLHttpRequest.open("POST","processAJAXError.asp",true);
    oXMLHttpRequest.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
    oXMLHttpRequest.send(sPostData);
    }
    }
     
    function 
    processErrorChange() {
    if (
    oXMLHttpRequest) {
    if (
    oXMLHttpRequest.readyState == 4) {
        if (
    oXMLHttpRequest.status == 200) {
         var 
    oXMLContent document.getElementById("XMLContent");
         if (
    oXMLContent) {
         
    oXMLContent.value oXMLHttpRequest.responseText;
         }
        }
    }
    }
    }
    }
    this.getResultValue getResultValue;
    function 
    getResultValue(oXML,sNode,iIndex) {
    var 
    sResult " ";
    if (
    oXML && sNode) {
    if (!
    iIndexiIndex 0;
    var 
    oNode oXML.getElementsByTagName(sNode)[iIndex];
    if (
    oNode) {
    if (
    oNode.firstChild) {
        
    sResult oNode.firstChild.data;
    }
    }
    }
    return 
    sResult;
    }
     
    this.setResultValue setResultValue;
    function 
    setResultValue(oXML,sNode,iIndex,sElmID) {
    var 
    sResult getResultValue(oXML,sNode,iIndex);
    var 
    oElm;
    if (
    sElmID) {
    oElm document.getElementById(sElmID);
    if (
    oElmoElm.innerHTML sResult.replace("*span*","<span ").replace("*closespan*","</span>");
    }
    return;
    }
     
    function 
    in_array(sNeedle,aHaystack,bCaseInsensitive) {
    sNeedle = new String(sNeedle);
    if (
    bCaseInsensitive) {
    sNeedle sNeedle.toLowerCase();
    for (
    i in aHaystack) if (aHaystack[i].toLowerCase() == sNeedle) return i;
    } else {
    for (
    i in aHaystack) if (aHaystack[i] == sNeedle) return i;
    }
    return -
    1;

    - Pip
    ---------------------------------------------------------------------------------
    Nothing takes the taste out of peanut butter quite like unrequited love.

  3. #3
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The XMLHttpRequest object is asynchronous, which means that it doesn't process immediately, but only after some time. Thus you can't return the result directly from your function. The way you handle this is with a callback. If for example your code looks like this :
    Code:
    function ajaxQuery(url) {
    	function stateChanged() { 
    		if (xmlHttp.readyState==4 || xmlHttp.readyState=="complete") {
    			// The Magical Value..... I want to move THIS
    			xmlHttp.responseText;
    		}
    	}
    
    	xmlHttp=GetXmlHttpObject(stateChanged)
    	xmlHttp.open("GET",url,true) 
    	xmlHttp.send(null) 
    }
    var usefulVar = ajaxQuery(url);
    alert(usefulVar);
    You should change it into :
    Code:
    function ajaxQuery(url, callback) {
    	var xmlHttp; // You should ALWAYS declare any local variables before using them
    	function stateChanged() { 
    		if (xmlHttp.readyState==4 || xmlHttp.readyState=="complete") {
    			callback(xmlHttp.responseText);
    		}
    	};
    
    	xmlHttp = GetXmlHttpObject(stateChanged);
    	xmlHttp.open("GET",url,true);
    	xmlHttp.send(""); // You should send "" rather than null, since Opera won't work with null
    }
    // create an anonymous function and pass it as the second argument
    ajaxQuery(url, function(usefulVar) {
    	alert(usefulVar);
    });
    This programming-style may take a bit of getting used to, but the upside is that you often get much better code, since you are forced to modularize your code more than else.

  4. #4
    SitePoint Addict Jack Matier's Avatar
    Join Date
    Feb 2005
    Posts
    292
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Okay, I'm going to look into the callback function now, it looks like a key to many things that I've wanted to do but could never figure out how.

    Thanks a bunch both of you.

  5. #5
    SitePoint Addict Jack Matier's Avatar
    Join Date
    Feb 2005
    Posts
    292
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Wow, that callback function is really neat.. Okay, what would you call what they are doing in this examples?

    http://twilightuniverse.com/2005/05/sack-of-ajax/
    http://twilightuniverse.com/projects/sack/tw-sack.js

    I'd like to learn that.. which I will after I get some rest... but I'd also like to easily find other written material on the same thing.

  6. #6
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The callback is also known as a lambda or anonymous function. Javascript is actually a functional language, which makes it quite different from most other languages. The fact that it has a java/c++ like syntax may decept this, which is an endless source of confusion for people who are new to javascript.
    Unlike thoose conventional languages, in javascript a function is a variable. This means that you can copy a function around just like you can copy a string around, or an object for that matter. The following syntaxes are completely interchangable :
    Code:
    function foobar() {
        alert("foobar");
    }
    Code:
    var foobar = function() {
        alert("foobar");
    }
    Well, actually they aren't completely interchangable, which has to do with how the parser works. As long as you declare the function before it's used, they are though.

    Quote Originally Posted by Jack Matier
    Wow, that callback function is really neat.. Okay, what would you call what they are doing in this examples?

    http://twilightuniverse.com/2005/05/sack-of-ajax/
    http://twilightuniverse.com/projects/sack/tw-sack.js

    I'd like to learn that.. which I will after I get some rest... but I'd also like to easily find other written material on the same thing.
    I had a look at sack before, and basically it just encapsulates the xmlhttprequest. I don't really see the point.

    If you're looking into using a library/framework, I'll recommend that you have a look at MochiKit.Async. The Deferred object is a way to make asynchronous programming a bit more streamlined. For example, you could issue your xmlhttprequest with the following code :
    Code:
    var d = doSimpleXMLHttpRequest(url);
    d.addCallback(function(transport) {
        alert(transport.responseText);
    });
    If you need something with a more framework approach than thoose two above, you could also take a look at freja, which is mostly relevant if you're building quite complex ajax-applications. If you're just trying to ajaxify a traditional webpage, it's overkill.
    I should mention that I'm biased, since I'm involved with the freja project.

  7. #7
    Employed Again Viflux's Avatar
    Join Date
    May 2003
    Location
    London, On.
    Posts
    1,130
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Does using a callback in that fashion eliminate the IE memory leak created by doing something like this...
    Code:
    onreadystatechange = function(){
      //stuff here
    }
    ?

    Or am I completely out to lunch?

  8. #8
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I don't think that would cause a leak in itself. IE leaks are mostly related to eventhandlers, registered on DOM-elements. (There are other ways to leak, but they aren't specific to IE)

  9. #9
    SitePoint Addict Jack Matier's Avatar
    Join Date
    Feb 2005
    Posts
    292
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by kyberfabrikken
    The callback is also known as a lambda or anonymous function. Javascript is actually a functional language, which makes it quite different from most other languages. The fact that it has a java/c++ like syntax may decept this, which is an endless source of confusion for people who are new to javascript.
    Count me in as one of those people. I've stuck functions inside of variables and called them up in event handlers before, but without really full well grasping what I was doing. I still write a lot of javascript the same way I do my php. Though I realize there are so many amazing things that can be done with javascript, yet it's quite a frustrating language, if only because (but not limited to) dealing with IE. Things in IE seem to be handled differently. My initial education was done at w3schools and the rest through various websites. After saying i'd head to bed I was up reading some documentation on developer.mozilla... and that's good.

    I had a look at sack before, and basically it just encapsulates the xmlhttprequest. I don't really see the point.
    I think what I was primarily wanting to know is the whole method they are using though. You say encapsulating..

    Code:
    ajax = new sack('mypage.php?var=lala');
    ajax.element = 'myexamplediv';
    ajax.runAJAX();
    
    function sack(file) {
       // Sets file to mypage.php?var=lala
       // ajax.element var becomes this.element
       // ajax.runAJAX() function becomes this.runAJAX() function?
    }
    So really it's not what I was actually looking for it seems. But it is interesting none the less, which is my purpose of looking at others code or frameworks for that matter.

    If you're looking into using a library/framework, I'll recommend that you have a look at MochiKit.Async. The Deferred object is a way to make asynchronous programming a bit more streamlined. For example, you could issue your xmlhttprequest with the following code :

    Code:
    var d = doSimpleXMLHttpRequest(url);
    d.addCallback(function(transport) {
        alert(transport.responseText);
    });
    If you need something with a more framework approach than thoose two above, you could also take a look at freja, which is mostly relevant if you're building quite complex ajax-applications. If you're just trying to ajaxify a traditional webpage, it's overkill.
    I should mention that I'm biased, since I'm involved with the freja project.
    Biased or not, I'll still look into it and definately screw around with the code. Though I'm not really a using another persons framework until I can understand what all the code does and can write it myself kind of guy. I admit I haven't followed this all the time with javascript but it seems to be a slower learning curve with me and some things are unavoidable.

    In ending, I try to be as modular as I can be, using as much knowledge as I know at the time so I don't have to repeat code or write it ever again. Everytime I learn a new tool like that callback thing it just makes me giddy because I know there are so many different places where I can use that. I'm also very strict with my formatting and a tab natzi (the very first thing I do when I get another persons code is go through and tab/format everything into place), and I try to call every variable ahead of time in javascript (but I'm not perfect), I held my head in shame when you pointed that out to me.

    Said that, I still go through this classical personal dilemna..
    Code:
    if () {
    
    } else {
    
    }
    
    vs
    
    if ()
    {
    
    }
    else
    {
    
    }
    I seem to be leaning towards the first lately ..

    Anyway, thanks for all the help, I think from here is the documentation on mozilla. I can't wait until I can consider myself a beginner at everything. I learned most of my stuff from other people's code, w3schools and various other tutorials.

  10. #10
    SitePoint Wizard
    Join Date
    Mar 2001
    Posts
    3,537
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Code:
    function ajaxQuery(url) {
    	function stateChanged() { 
    		if (xmlHttp.readyState==4 || xmlHttp.readyState=="complete") {
    			// The Magical Value..... I want to move THIS
    			xmlHttp.responseText;
    		}
    	}
    
    	xmlHttp=GetXmlHttpObject(stateChanged)
    	xmlHttp.open("GET",url,true) 
    	xmlHttp.send(null) 
    }
    
    // Over to here :)
    var yippie=ajaxQuery('url')
    I can alert it from there and I can assign it to a variable (though not a global variable?), but I can't seem to return it from inside of two functions.
    Your stateChanged() function is an event handler function because it gets assigned to the onreadystatechange event by these lines:
    Code:
    function ajaxQuery(url, callback) {
    	var xmlHttp; // You should ALWAYS declare any local variables before using them
    	function stateChanged() { 
    		if (xmlHttp.readyState==4 || xmlHttp.readyState=="complete") {
    			callback(xmlHttp.responseText);
    		}
    	};
    
    	xmlHttp = GetXmlHttpObject(stateChanged);
    	xmlHttp.open("GET",url,true);
    	xmlHttp.send(""); // You should send "" rather than null, since Opera won't work with null
    }
    Code:
    function GetXmlHttpObject(handler) { 
    	var objXmlHttp=null
    	
    	if (navigator.userAgent.indexOf("Opera")>=0) {
    		alert("Not currently working for Opera.. I'll have to grab this later... because AJAX can work in opera 7+ I hear...");
    		return 
    	}
    	if (navigator.userAgent.indexOf("MSIE")>=0)	{ 
    		var strName="Msxml2.XMLHTTP"
    		if (navigator.appVersion.indexOf("MSIE 5.5")>=0) {
    			strName="Microsoft.XMLHTTP"
    		} try { 
    			objXmlHttp=new ActiveXObject(strName)
    			objXmlHttp.onreadystatechange=handler 
    			return objXmlHttp
    However, you can't return values to your script from an event handler function. Backing up a bit, when a function is called, the function call is replaced by its return value. For instance:
    Code:
    function myFunc(num)
    {
         return num * 2;
    }
    
    var result = myFunc(10);
    The return value replaces the function call to produce:
    Code:
    var result = 20;
    Now back to your code. Where is the function call for your eventhandler function? All you have is this:
    Code:
    objXmlHttp.onreadystatechange=handler
    That is not a function call because to call a function, the function execution operator '( )' has to appear somewhere in the code. Well, where is the function call then? You certainly know that your function gets executed somehow when the event fires. The answer is: the function call takes place behind the scenes by js. There's a js curtain drawn across the stage that hides the mechanizations taking place on stage--all you know is that you gave a function reference to js, and at some point js calls the function. As a result, if you return a value from your event handler function, it gets sent to the function call behind the js curtains and for all intents and purposes disappears--never to be seen again. (As I assume you know, you can return true or false from an event handler function, and in most situations sending false behind the js curtains will cancel the event, but that's the extent of what an event handler function can return.)

    However, you can certainly call another function you defined from within an event handler function, like this:
    Code:
    objXmlHttp.onreadystatechange = function stateChanged() 
    { 
    		if (xmlHttp.readyState==4 || xmlHttp.readyState=="complete")
    		{
    			// The Magical Value..... I want to move THIS
    			myFunc(xmlHttp.responseText);
    		}
    }
    
    var yippie = "";
    function myFunc(text)
    {
    	yippie = text;
    }
    Hope that helps.

    p.s. All your lines should end with a semi-colon.

  11. #11
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Great explanations, kyber!

    I'd like to see the terminology more accurate though.

    Quote Originally Posted by kyberfabrikken
    The callback is also known as a lambda or anonymous function.
    The correct term here is closure

    Javascript is actually a functional language, which makes it quite different from most other languages.
    JS lacks some important features to deserve the 'functional' title. I'd say, it's a "language with first class functions" (just like PHP is a "language with objects", not "object oriented" ).

    The fact that it has a java/c++ like syntax may decept this, which is an endless source of confusion for people who are new to javascript.
    Unlike thoose conventional languages, in javascript a function is a variable.
    C function can be assigned to a variable as well, that's not the point. The power of javascript is that functional variables preserve bindings, i.e. they are closures. Java has a limited support of closures.

  12. #12
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by stereofrog
    Great explanations, kyber!

    I'd like to see the terminology more accurate though.
    Thanks, I can always rely on you to correct me (And i do mean that in a positive sense).

    Quote Originally Posted by stereofrog
    The correct term here is closure
    So, would it be correct to say that lambda is the functional expression itself, whereas a closure is a concrete variable, representing that expression in the sourcecode ? Or is lambda nothing more than the (rather random) symbol picked to signify a function in (a certain kind of ) algebra, and then adopted by the geeks who invented functional programming languages ?

    Quote Originally Posted by stereofrog
    JS lacks some important features to deserve the 'functional' title. I'd say, it's a "language with first class functions" (just like PHP is a "language with objects", not "object oriented" ).
    Well, JS is a hybrid - it has a little of everything. Since it's my only real exposure to functional programming, I tend to emphasize that.

  13. #13
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by kyberfabrikken
    So, would it be correct to say that lambda is the functional expression itself, whereas a closure is a concrete variable, representing that expression in the sourcecode ? Or is lambda nothing more than the (rather random) symbol picked to signify a function in (a certain kind of ) algebra, and then adopted by the geeks who invented functional programming languages ?
    In my understanding lambda is a function constant, i.e. function that expresses itself (just like numeric constant "10" expresses itself, i.e. "ten"). Closure (=code+bindings) is an internal datatype, when compiler encounters the function constant, it creates the closure (continuing the analogy, constant "10" creates a 32-bit floating point number).

    My point was that callbacks don't have to be lambdas (=constants). Strictly speaking, they don't have to be closures too, however, this is how they're mostly used.

    Ah, and sorry for carping! I just followed the principle: "if not understanding something, try to explain it to someone else"

  14. #14
    SitePoint Addict Jack Matier's Avatar
    Join Date
    Feb 2005
    Posts
    292
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks for this educationsal show guys. I've bookmarked this because I know I'm going to refer back on it at some point.

    The answer is: the function call takes place behind the scenes by js. There's a js curtain drawn across the stage that hides the mechanizations taking place on stage--all you know is that you gave a function reference to js, and at some point js calls the function. As a result, if you return a value from your event handler function, it gets sent to the function call behind the js curtains and for all intents and purposes disappears--never to be seen again.
    Incidently, this didn't dawn on me until quite a bit later when I was replying to kyber, and even then it was only partly so. Thanks for explaining that though, it really helped me (I mean that after reading it 10 times over).

    Wish I had more to say.

  15. #15
    SitePoint Evangelist pip's Avatar
    Join Date
    Jun 2001
    Location
    Cape Town, South Africa
    Posts
    548
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Jack Matier
    Said that, I still go through this classical personal dilemna..
    Dude... that is one thing I'm really struggling with myself. It's very annoying having to change code from the "wrong way" to the "right way", whichever is which for you, but I believe in line-space saving... the more I can do on one line without having to waste another, the better I manage to read and understand the code
    - Pip
    ---------------------------------------------------------------------------------
    Nothing takes the taste out of peanut butter quite like unrequited love.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •