tags:

views:

297

answers:

6

In my feeble attempt to learn JavaScript, I bought a book which teaches you how to do things in JavaScript, but forgets to mention WHY.

Coming from PHP I am familiar with the typical function syntax:

function name() {return;}

which from what I understand works the same in JS.

Then I decide I want to attempt to use the YUI 3 framework for a small project to continue learning and come across this...YUI Global Object

YUI().use('node', function(Y) {
   Y.Node.get('#demo');
});

As far as I understand this is using the 'use' function of the YUI() object, passing 'node' to the 'use' function....but then what...why is it declaring a function within another function call?

Could someone please explain the syntax being used here?

Also a good reference that explains JavaScript general syntax's similar to php.net would also be beneficial. Thanks for your help.

A: 

It is an anonymous function (akin to lambda function) declaration.

YUI().use('node', function(Y) {
   Y.Node.get('#demo');
})

In Javascript, functions are 1st class citizens - they are objects like any other; hence, they can be passed as parameter.

jldupont
+2  A: 

In JavaScript, functions are objects. In that case, they are passing in an object as the second parameter value (and defining it inline).

YUI().use('node', function(Y) {
    Y.Node.get('#demo');
});

is the same as this:

var xxx = function(Y) {
    Y.Node.get('#demo');
};

YUI().use('node', xxx);
Gabriel McAdams
No, not everything in Javascript is an object.
kangax
@kangax: You're right, and I modified my answer to make it more accurate. Please reconsider you're downvote.
Gabriel McAdams
+2  A: 

This is constructing an anonymous function, and then passing the function itself in as an argument to use. The use method will then call your anonymous function with a value, which in your function will be called Y, which contains the modules that you asked for in the previous arguments to use.

This is essentially equivalent to the following, which passes myFunction in as a callback to YUI().use, except that the anonymous function doesn't have a name:

function myFunction(Y) {
   Y.Node.get('#demo');
}

YUI().use('node', myFunction);

This pattern is used because JavaScript doesn't have any kind of explicit notion of namespaces or modules. They can be emulated, however, by using the scope of a function to act as a sort of namespace. In this case, YUI().use will construct an object that has all of the functionality that you request, and pass that object in to the function you provide, so you can use that Y object to call methods that you have imported.

For a good online reference on JavaScript syntax and methods, I like to use the Mozilla Developer Center documentation. In particular, they have good references on JavaScript and the DOM. As it is part of the Mozilla project, they focus on the methods and syntax supported by Gecko (the rendering engine of Firefox), but they usually include compatibility notes to mention what is portable and what is specific to Gecko.

For your question, I would recommend reading the MDC documentation on functions and function scope. Sadly, the MDC doesn't usually come up on top on a Google search; instead, you get W3Schools, which tends to be lower quality and have more ads. I've found it useful to always prefix my searches for anything about JavaScript or the DOM with "mdc" in order to get the MDC documentation; so, for instance, to find that link, I searched for mdc function, and found what I needed.

Brian Campbell
+1  A: 

In javascript, functions can be passed around as variables. So, here's some other ways that the YUI code could have been written

//original
YUI().use('node', function(Y) {
   Y.Node.get('#demo');
});


//more traditional "global function" 
function useNode(Y) {
    Y.Node.get('#demo');
}
YUI().use('node', useNode);


//local callback function
var myUseNode = function(Y) {
    Y.Node.get('#demo');
}
YUI().use('node', myUseNode);

edit As for the second half of your question, you could write what I know about PHP on a postage stamp, so I can't help you there, sorry :-)

Dan F
A: 

What is being shown is what is known as an anonymous function that is being passed as an argument to a function. I don't think PHP has first-class functions like this, so I have no idea how to explain the syntax in terms of that (I also don't do much with PHP, so..)

Here is my example code:

function something_random(a) {
    alert("the type of a is ... " + typeof(a));
    if (typeof(a) === 'function') {
        a();
    }
}

Now with this function in mind, you can plug this into Firebug or something similar and run the following code:

something_random(function () {
    alert("This is a test.");
});

Something interesting will happen here - you will get two alerts. One should say "the type of a is... function" and the other should say "this is a test." This is because in JavaScript - as well as some other languages - functions are treated just like objects (well, they technically are objects.)

You can throw around functions all day if you like - they are just like numbers, arrays, and so on.

Something interesting can also happen. You can also pass arguments into anonymous functions, which is something that jQuery does quite a bit (except it uses call, but we won't go there.) This is where you get the special things like where you put function(d) {} in a code.

Hope this helps.

Reid
+5  A: 

Its an anonymous function. Its considered a callback.

In PHP 4 and early versions of PHP 5 you might see something like this:

PHP

function callback($var){
   ...
}

array_filter( $array, "callback" );

In later versions of PHP 5 you can define them as anonymous functions inline.

So, in JavaScript, the old version would look like this:

JavaScript

function use_callback(Y){
    Y.Node.get('#demo');
}

YUI().use('node', use_callback);

But by defining an inline anonymous function, you can save the extra clutter and defined function:

YUI().use('node', function(Y) {
   Y.Node.get('#demo');
});

Both those functions are equivalent.

Doug Neiner
thanks for the php reference, really helped clear that up.