Decoding the JavaScript syntax of function(event) {} - javascript

I've just come across this little snippet of JavaScript code online:
exampleSocket.onopen = function(event) { // rest of code here;}
And I'm rather confused about the function(event) part, as there are no comments for me to analyze. (Who needs comments when you're designing bi-directional duplex connections? Haha ).
What exactly is function(event)? I always thought you had to define a function name with the function in javaScript. Is this an example of bad code? Additionally, the (argument-parameter-whatever) 'event' isn't even defined anywhere else in the code. Just bam. There it is. Is it necessary to define that, or is (event) a special predefined value? Lastly, if you were to replace (event) with some other value like (e), would the code still work?
Thanks

What you've got there is a function expression, not a function statement.
In a function statement, the name is mandatory. In a function expression it is optional. A function expression with a name is called a named function expression. A function expression without is called an anonymous function
There are a number of subtle differences between all these different methods of declaring a function which are covered in this question; var functionName = function() {} vs function functionName() {}
What you're doing here is setting the onopen property of exampleSocket to a function (expression). Note that you are not running that function at all; you are simply declaring it, and saving a reference to it in exampleSocket.onopen.
This means that someone can execute that function when they want to by calling;
exampleSocket.open();
They can pass a parameter to the function, which you can use inside the function using the event variable (and to answer your question; event is not a special word. You can call it anything).
exampleSocket.onopen = function (event) {
console.log(event); // will log "hello"
};
exampleSocket.open("hello");
The fact the variable event isn't used anywhere will likely mean the developer has named the argument to say "hey, look, you can use this if you want to", but hasn't in his actual implementation.
You don't have to declare the variable yourself. It is declared already by being named in the argument list, and it will be initialized to a value when someone passes an argument when they call the function.
Note that we could define this event handler using a function statement;
function foo(event) {
console.log(event);
}
exampleSocket.open = foo;
... or via a named function expression:
exampleSocket.open = function foo(event) {
console.log(event);
};
To confuse things (don't worry about this; it's a quirk of JavaScript) the name of a named function expression is only available inside the function itself;
exampleSocket.open = function foo(event) {
console.log(event);
console.log(typeof foo); // you'll get "function"
};
console.log(typeof foo); // you'll get "undefined"
... but in a function statement, you'll be able to access the name both inside and out.
I hope this helps... it's a bit of a "brain dump" of information :).

This is an anonymous function. A function is a value, and you can declare and store functions like this. More information on that syntax in this question.
Reading the code (I don't think it needs any more comments than it already has), you are writing a handler function which is called when the socket opens. The socket open event will be passed to the function in the variable event.
Why event? Because the API, whatever it is, expects to pass in an argument that represents the 'open' event.

It's a simple and common JS event-binding function.
It attach an anonymous function to the "open" event of "exampleSocket".
When such event is fired the declared function is called.
Each event may have some parameters, which contain additional info about the event itself.
You can name that parameter the way you want ("event","e" or "anythingElse") and then you can refer to it in the anonymous function body.

You are basically assigning a function value to exampleSocket.onopen, which can then be called elsewhere. Imagine something like this:
var obj = {};
obj.onsomething = function(a, b, c, d) {
alert(a+b+c+d);
};
obj.onsomething(1, 2, 3, 4);
In this case, I gave obj.onsomething a function that takes 4 parameters (should be numbers) and alerts the sum. Then I can just call obj.onsomething with 4 parameters.
So the function that you assign to exampleSocket.onopen will get called when it is appropriate (for example, when the socket is open).
Hope that helps.

Related

I need some explanation about some syntax

I have seen this kind of code in one of Google's google maps documentation. My question is about the listener. Instead of the callback function passed immediately after the 'click' action the showArrays() function is called but not passed nothing as parameter. On the other hand showArrays() function uses event as parameter. Please explain me this kind of calling the function.
element.addListener('click', showArrays);
//some code here
}
function showArrays(event) {
// some code here
}
Think of the names of functions as variables themselves. showArrays is a variable, that, when given an event, does something with it.
You can pass the functions name as a parameter to addListener so that it can call the callback when the element is clicked on. It's important to note that you are not calling the function in the first line, only passing a reference to that function.
You can show this property in the browser's console with this test:
function test() { console.log("Test was called"); }
Notice if you say var x = test nothing is printed to the console. But if you say var x = test() you see the print. Finally, if you do var x = test; x() you will see the print out, because you called the test function after assigning it a new name.
Notice that in the element.addListener('click', showArrays) line, showArrays does NOT have brackets after it. That means it's not being called. Instead, the entire function is being passed as a parameter to the addListener method.
Event listeners in JS will take the handler function you provide when you attach them with addListener (or addEventListener, more commonly), and, when the event occurs, they will call that function and pass an event object to it.
In other words, showArrays is not being called until the element is clicked, and all event listeners inherently get passed an event object at that point, detailing the specific properties of the event.
One of the syntax cases for describing a function is:
var showArrays = function (event) {
// of the code here
}
and it is precisely this argument value that the addEventListener method uses, and even other functions such as setTimeout or setInterval, among others.
addEventListener method always sends the "event" object as an argument to the callback function. When you use the anonymous function, it is obvious to see it:
element.addEventListener('click', function(event) {
// some code here
});
But when you send to the addEventListener method a link to the function you want to be called when the event occures (in your case it is a link to showArrays function), addEventListener sends "event" object as an argument to this function just on itself. So, although it's not obvious to see it, but the "event" object is being sent to showArrays function automatically.
element.addEventListener('click', showArrays); // the event object will be sent automatically
And you will have an access to the "event" object inside the showArrays function. But, of corse, in showArrays function declaration you should have a parameter for catching the "event" object.
function showArrays() {} // it's not going to work
function showArrays(event) {} // it will work

JavaScript examples, clarify the langue pattern design for functions with-in functions

I am learning JavaScript and becoming confused by the logic of the code examples. From codecademy. Why are there function set-ups in function calls?
I'm quite confused. I am moving from a simplified C-like langue.
The JavaScript example
var main = function(){
$('.article').click(function(){
$('.description').hide();
$(this).children('.description').show();
});
};
My understanding:
- main is a function name with a return type of var.
$('.article') is a element/object/or class object.
.click() is a call to a member function
But:
???:
.click(function(){
$('.description').hide();
$(this).children('.description').show();
});
This seems to be a newly on the spot created function to run When/If click() is activated or run.
The way I used to think is like this:
var *p_obj = $('.article');
var *p_obj = $('.description');
var do_click()
{
p_obj2.hide();
p_obj.children(p_obj2).show();
}
var main(){
p_obj.click(do_click);
}
Function main() looks at p_obj and calls click().
Click() evaluates to true/false and run the pointer_to function do_click().
Function do_click() looks at the p_obj2 and calls hide(), which performs an action of hiding the p_obj2.
Function do_click() also looks at p_obj and uses children to scope focus to p_obj2, then it runs show(), which preforms an action of displaying p_obj2.
I do realize my C-like example is wrong and odd. I realize my terminology is wrong or otherwise used incorrectly.
The way this design looks seems like I must write extended functionality on-the-spot for every call to .click(), so if-then .click() is run on 3 different items, I'm creating different extended functionality for each object. But I would normally create a single function that varies it's internal execution based on the object or condition click() calls it by.
This set-up seems alright if the code a relatively simple or short, but on-the-spot functional seems like overworking for longer code and code where the functionality repeats but the objects change.
Am I thinking about JavaScript functions with-in functions correctly and is this a design goal of the langue to add long repeating extended functions with-in functions?
Here, you should understand 2 things:
passing functions as arguments
anonymous functions
The first concept is particulary important because callbacks are popular in JavaScript, so let me explain it for callbacks. Imagine we have 2 functions getStuffFromWeb and processStuff. You probably expect that they are used like this:
var result = getStuffFromWeb();
processStuff(result);
But the issue here is waiting for getStuffFromWeb may take some time (the server is busy), so instead they are usually used in a "when you finish, call this function" manner, which is:
var getStuffFromWeb = function(params,callback) {
...
callback(result);
};
getStuffFromWeb(someParams,processStuff);
Well, in fact the structure of getStuffFromWeb will be different, most likely something like this:
var getStuffFromWeb = function(params,callback) {
requestObject.make_request(params)
.onSuccess(callback);
};
So when getStuffFromWeb is called, it starts to listen to response while the code after getStuffFromWeb(someParams,processStuff); goes on evaluating. When the response comes, it calls the callback function to process the data further using the procedure we have defined (processStuff).
The second concept is rather simple: you may of'course write smth like
var processStuff = function() {...};
var getStuffFromWeb = function(params,callback) {
requestObject.make_request(params)
.onSuccess(callback);
};
getStuffFromWeb(someParams,processStuff);
but if you use processStuff only once, why define a named function? Instead, you can just put the very same expression inside the onSuccess param like this:
var getStuffFromWeb = function(params) {
requestObject.make_request(params)
.onSuccess(function() {...});
};
getStuffFromWeb(someParams);
This looks exactly like if we took the value of processStuff and put it directly to the onSuccess's argument (and that's called anonymous function). And also we got rid of an extra argument of getStuffFromWeb.
So basically that's it.
Simple answer is that the second argument of click() requires a callback function.
This can be a named function passed as reference as in your p_obj.click(do_click); example or it can be an anonymous function with self contained logic. Anonymous functions are very common in javascript
It's the same thing just with 2 different ways of declaring the callback.
Note that the only time you would return anything from an event handler function would be to return false which effectively prevents the default browser event (url opening from href or form submit for examples) and stops event propagating up the DOM tree
main is a function name with a return type of var.
No. main is a variable which is assigned an anonymous function. The function name would go between the keyword function and the () containing the argument list.
It has no return statement so it returns undefined.
$('.article') is a element/object/or class object.
It is a call to the function $ with one argument. The return value is a jQuery object.
.click() is a call to a member function
Pretty much. In JavaScript we call any function that is the value of a property of an object as method.
This seems to be a newly on the spot created function
function () { } is a function expression. It creates a function, exactly like the one used to assign a value to main earlier. This question is worth reading for more on the subject.
When/If click() is activated or run.
The click function is called immediately. The new function is passed as an argument.
The purpose of the click function is to bind a click event handler so that when a click event hits the element later on, it will trigger the function passed as an argument.
I do realize my c -like example is wrong and odd. I realize my terminology is wrong or otherwise used incorrectly.
Leaving aside vagaries of syntax. The main difference here is that the click event handler function is that the event handler function is stored in an intermediary variable.
You can do that in JavaScript just as easily, and then reuse the function elsewhere in the code.
var main = function(){
function show_specific_description() {
$('.description').hide();
$(this).children('.description').show();
}
$('.article').click(show_specific_description);
show_specific_description.call($(".article").last()[0]);
};
main();
is this a design goal of the langue to add long repeating extended functions with-in functions?
No. Passing a function expression as an argument is a convenient way to be more concise when you don't want to reuse the function. It's not the only way to pass functions about.
main is currently a function.
It is possible to be overwritten (even to a different type). var is not the return type, it's a statement that main is a variable.
All values should be declared as variables, within the highest scope you intend them to be used (in JS, scope typically means functions, not blocks).
You have the right idea, suspecting that the function gets passed in, and called at a later point in time (and this is actually one of the harder parts for people to get, coming from certain other languages). You'll see this behaviour all through JS.
One key thing to keep in mind in this language (you haven't hit it yet, but you will) is that JS is lexically scoped.
function getInnerX () {
var x = 5;
function getX () {
return x;
};
return getX;
}
var x = 10;
var getX = getInnerX();
console.log(getX()); // 5
The function getX inside of getInnerX has access to the references around it, at the point where it's defined (not where it's called), and thus has live access to the inner x, even if its value changes over time.
This will be another important piece of understanding what you see going on in the language, especially in the case of callbacks.

About function in javascript

Sorry for the rather beginner question. What's the differences of function usage between
$(document).keypress(function() {
//some code
});
and
var somethingElse = function() {
//some code
};
I know the latter is to create a function similar to Java's
public void somethingElse() {
//some code
}
but I always assume the former as anonymous function that act inside a method. Can someone shed me some light regarding this? Thanks.
The first one is a jQuery shortcut to create an event listener.
It's equivalent to:
document.addEventListener('keypress', function() {
// some code
});
More info: http://www.w3schools.com/jsref/met_document_addeventlistener.asp
Now, about named or anonymous functions, what's the difference between
var doSomething = function() {
// some code
};
and this?
function doSomething() {
// some code
}
There's no difference for the developer. Of course there's a difference on memory, but in javascript developers don't have to take care of it.
Actually for the case of an event handler or other techniques that use callback functions, you can pass an anonymous function or a previously declared one, it's exactly the same:
$(document).keypress(doSomething);
or
$(document).keypress(function() {
// some code
});
creates an anon function and passes it to the handler
creates an anonymous function and a variable that references it.
creates a named function - that is hoisted
the hoisted function becomes available to you at any line within your function scope, while the non-hoisted function will be undefined until the line where it is declared runs.
there is no difference between #2 and #3 (other than the hoisting) - some people think that the first one creates an object and the 2nd one is some magical thing, or a global function, but nope - they are both function objects within your scope.
The former is a callback, meaning some instructions that will be executed ONLY as soon as the keypress event in your example is triggered.
Thus, a function's name is not required.
Function expressions, the latter, is mostly used when adding an object's property acting as a method like:
var myObject = {};
myObject.sayHello = function() {
alert("Hello");
}

What is the meaning of 'function(event)' in js

I don't know the meaning of the sentence 'function(event)'
Event.add(apple,'click',function(event) {
Event.stopPropagation(event);
});
Isn't the argument 'event' is the unique keyword of javascript?
Is keyword can be an argument of some function?
I understand the meaning of below code :
function(test) {
alert(test);
}
But I don't understand this one :
function(event)...
Can any one give an explanation about that to me?
The event object is always passed to the handler and contains a lot of useful information what has happened.
Different types of events provide different properties. For example, the onclick event object contains:
event.target - the reference to clicked element. IE uses event.srcElement instead.
event.clientX / event.clientY - coordinates of the pointer at the moment of click.
Information about which button was clicked and other properties.
Please visit this link.
It answers all your questions very simply
Source http://javascript.info/tutorial/obtaining-event-object
Example:
Like if in HTML you have assigned an event like this
<button onclick="alert(event)">See the event</button>
then
function alert(event) {
// event.type contains whether this event was invoked in the result of a click etc
// event.target would contain the reference to the element which invoked this method/event
}
It is an anonymous function, that is a function without name, that sends the event object. That object contains information about the event itself. It is always passed as first object/variable.
It is defining an anonymous function object. This code:
function foo(bar) { ... }
Is functionally similar to:
var foo = function (bar) { ... };
(Except that in the first case the name foo and the creation and assignment of the function object are hoisted to the top of the scope, while in the second case only the name foo is hoisted; foo won't hold the function until the assignment executes.)
Effectively, the code you posted is calling Event.add() and passing a function to it as the third argument, but rather than declaring the function ahead of time it is creating the function object inline.
Another way to write the code block in your question is:
function handler(event) {
Event.stopPropagation(event);
}
Event.add(apple, 'click', handler);
Except that the code in your question does not introduce the handler name.
Note that there is no such method Event.stopPropagation(). However, the event object will have a stopPropagation(), so the capital E was probably a typo. It's likely that the intent was to use function (event) { event.stopPropagation(); }.
event is just a variable that's passed to event listener functions such as Event.add, element.on. It's not reserved (although Event is, which is why you can use Event.add), and you can name it whatever you like.
The event argument is used to pass information about the event that has happened (the click on apple in this case), which can be used to retrieve data about the event or manipulate it.
function(){...} is an anonymous function, which means that you don't need to name it, you can just declare it inline, and the function will be passed as an argument, as if you said
function foo (event) {
...
}
Event.add(apple, "click", foo);
but you don't need to declare it before hand. It does come at the disadvantage of not being duplicable, for instance when clearing an event handler.
Look at the event variable and you will all understand :)
function (event) {
console.log({ event });
}

Adding multiple event listeners in javascript to element

I've got a small drag and drop set up up and running, but it's using inline javascript and I'd prefer to move it all to an external file. Theoretically it's an easy swap, but I'm getting referenceErrors in my inspector and my minifcation is failing.
From what I can tell, the issue is coming from the return.
Original HTML
<section id="titles" ondrop="dropClip(this, event)" ondragenter="return false" ondragover="return false"></section>
Desired HTML
<section id="titles"></section>
JavaScript
var titles = document.getElementById('titles');
titles
.addEventListener('drop', dropClip(this, event))
.addEventListener('dragenter', return false)
.addEventListener('dragover', return false);
Javascript is a language where functions are "first-class objects". This means, possibly contrary to other programming languages that you may have experience in, that you can treat a function like any other object: you can pass it around, you can return it, you can have a function with a function inside it with a function inside it, and so on.
The consequence of this may be a very unexpected programming style required to be successful in Javascript. In other languages, UI event binding occurs in a variety of ways (such as C#'s Button1.Click += new System.EventHandler(this.myEventHandler);, or Classic VB's Button_Click()). In C#, you can pass around delegates, which are special objects with a specifically defined set of parameters and return values, to which a function can be bound. But all that disappears in javascript because you can simply attach a function to a property directly. For browser DOM event handling, the property is assumed to be a function reference, and during the native event handling code for that event, it calls the function attached to the property with the same name as the event.
Okay, you say, we have functions. And we can pass them around and treat them just like variables. Now what?
First, please take special note that the following two functions declarations are identical. They yield the exact same result, of declaring a function named myfun in the current scope (in a browser, the window object or the current function that is running).
function myfun(param1, param2) {
//do some stuff
};
var myfun = function (param1, param2) {
//do some stuff
};
(Actually, the first one will end up with a name property that the second one won't, and possibly some other minor differences, but for all practical intents and purposes they are identical).
The first one is just a shortcut for the second one. Basically, you create a function (that may or may not have a name) and assign it to a variable. Programmers use the convenient shortcut of calling the result "the myfun function", but in reality the case is "the myfun variable--which contains a particular function right now".
You can get many references to the same function--which is a true object--just by assigning it to other variables:
function myfun(param1, param2) {
//do some stuff
};
var a = myfun, b = myfun, c = myfun;
a(); // runs `myfun`
b(); // runs `myfun`
c(); // runs `myfun`
The next thing to notice is that to invoke a function, you must use parentheses after its name, and any parameters go inside the parentheses.
var result = myfun('a', 1); // invoke the `myfun` function
// and store its return value in variable `result`
But take a look back at our assignment statement making a, b, and c all be aliases of the myfun function: in those cases we didn't use parentheses, because--and here is where it gets really important, so pay attention:
To invoke a function (and get the function's return value), use parentheses after its name.
To pass a function reference, do not use parentheses.
What if we had done this instead:
var a = myfun(), b = myfun(), c = myfun();
a, b, and c would no longer be pointers to the myfun function. They would all be the result of myfun and would contain whatever myfun returned--or undefined if it didn't return anything. If you tried to invoke one of these, say a() you would get some error similar to:
> TypeError: a is not a function
Now that I've painted all that background, there is one simple thing to know that will get you on track to being successful with addEventListener: it expects a function as the second parameter. In your example code, you've put the contents of functions you'd like to run when addEventListener calls them, but no actual functions.
You can solve that by actually declaring the functions first, such as:
function doNothing() {
return false;
}
titles.addEventListener('dragenter', doNothing);
// Note: this is not invocation like `doNothing()`, but passing a reference
Or, you can simply wrap your function statements into an anonymous function. Remember, functions in javascript don't actually have names, we just have variables that contain functions. An anonymous function is one that has no name at all, and it is invoked either by an implicit name assignment (such as being passed as a parameter--where it will have the parameter's name) or by being directly invoked by doing the magic invocation action of putting parentheses after it.
That would look something like this:
titles.addEventListener('dragenter', function () { // anonymous function
return false;
});
If you want to invoke an anonymous function, you do have to let javascript know you want to treat it like a value as opposed to the normal shortcut-method of creating a named function in the current scope (where function myfun is treated like var myfun = function). That is done by wrapping the entire thing in one more set of parentheses, like this:
(function () { // begin a function value containing an anonymous function
// do something
}()); //invoke it, and close the function value
I hope this helps you understand more about javascript, why your code was not working, and what you need to do to make it work.
For sure you have to wrap the function contents you give to addEventListener into a function.
For instance instead of .addEventListener('drop', dropClip(this, event)) you will write .addEventListener('drop', function(event) { dropClip(this, event); })

Categories