I followed a little tutorial on Drag & Drop in HTML with Javascript, found here:
http://www.html5rocks.com/tutorials/dnd/basics/
The problem is, I'm working with an in-house style restriction. Meaning all documents have to be written to standards that everyone here uses.
For Javascript, one of them is to always write functions in the object-notation.
I.e.
var myFunction = function() {}
instead of
function myFunction() {}
In this tutorial, the events for the HTML5 drag & drop are added via the addEventHandler() function. This requires you use the normal notation, because if you use the object-notation, the addEventHandler() function trips over it for some reason.
I tried re-writing everything to be like this, without addEventHandler:
myElement.dragstart = function(e) {}
But non of it worked. Using the normal notation with addEventHandler however, everything works like a charm.
I just wanna make sure: am I overlooking something or should this work? Part of me suspects this is just not supported properly yet and you need to use addEventHandler. Is this the case?
Setting the dragstart property vs using addEventHandler('dragstart', ...) is not just a matter of notation. You can and should stick with addEventHandler. There should be no problem, however, using this "style:"
var myFunction = function() {}
myElement.addEventListener('dragstart', myFunction, ...);
Edit
Okay, so this doesn't directly answer the question, but I feel it does need to be addressed in this context.
Writing
var myFunction = function() {}
instead of
function myFunction() {}
is not any sort of "object notation." The first is a function expression, since it's part of an AssignmentExpression. The second is a function declaration. What's the difference? kangax explains it really well:
First of all, function declarations are parsed and evaluated before any other expressions are. Even if declaration is positioned last in a source, it will be evaluated foremost any other expressions contained in a scope.
...
Another important trait of function declarations is that declaring them conditionally is non-standardized and varies across different environments. You should never rely on functions being declared conditionally and use function expressions instead.
Do the people who set the JavaScript code standards in-house really understand the subtle differences?
Point number 1: that's a stupid rule. There are two ways of naming a function for a good reason, and ignoring that to specify one style is fairly dim, IMO.
Your problem is, I think, that your function hasn't been defined by the time you get to addEventHandler. This is because of something called "hoisting". In this process, functions named with the function myFunction() {} syntax are "hoisted" to the top of the function. So if you invoke them anywhere in the function, the function will work. For instance, this will work:
el.addEventListener('click', foo);
function foo() {}
Functions named in your organisation's style, however, are not hoisted. The variable declaration is, but the value is not set until that line of code is reached. So this will not work:
el.addEventListener('click', foo);
var foo = function() {};
The easiest way to get around this would be to move all your function definitions to the top of the scope, unless there is a good reason to define them later. So this will work:
var foo = function() {};
el.addEventListener('click', foo);
Related
I've seen IIFE's written:
(function() {
console.log("do cool stuff");
})();
as well as:
(function() {
console.log("do more cool stuff");
}());
They seem to work the same in any context I've used them, though in cases I've been told one way is right and the other is wrong, vice versa. Does anyone have any solid reason or logic as to it being written one order over the other? Is there some cases where there could be potentially more going on after the function body closes but before the invoking parenthesis come into play, or after but before that final closing parenthesis? I've mostly used these in an Angular module closures and can't seem to find anything on any real reason to go one way or the other, wondering if anyone had different experience.
Short answer: It doesn't matter, as long as you put them there.
Long answer: It doesn't matter except in the case of arrow functions, because for JavaScript the only important thing is that they are there. The reason for this is that the language spec defines that a statement must only start with the function keyword if you declare a named function. Hence, it is against the spec to define an IIFE like that:
function () {}();
The workaround for this is to wrap the entire thing in parentheses, so that the statement does not start with the function keyword anymore. You achieve this by using
(function () {})();
as well as by using:
(function () {}());
Which one you choose is completely arbitrary and hence up to you.
I (personally) put the parentheses around the function, not around the call, i.e. like this one:
(function () {})();
Reason: I want to use the smallest portion of code to be wrapped in something that is only needed for technical reasons, and this is the function definition, not the call. Apart from that the spec says that you can not define a function in that way, it is not about calling the function. Hence, I think it's more clear if you wrap the definition, not the call.
edit
However, in the case of the arrow function in es6, the invocation must be outside of the wrapper. It being inside the wrapper causes an unexpected token error on the opening parenthesis of the invocation. Not totally clear on the mechanics of why this is so.
I recently joined a large software developing project which uses mainly JavaScript and a particular question has been on my mind since day one. I know this issue has been here on SO before, but I have never seen the core question being properly answered. So here I ask it again:
Are there any benefits in JavaScript in using function expressions rather than function declarations?
In other words, is this:
var myFunction = function () {
// Nice code.
}
in any way better than this:
function myFunction () {
// Nice code.
}
As I see it, function expressions only introduce negative aspects on several levels to the code base. Here I list a few.
Function expression as the one above, suddenly forces you to be careful with forward references, as the anonymous function object that the myFunction variable refers to, does not exist until the variable expression actually executes. This is never a problem if you use function declarations.
Apart from generating twice as many objects as in the case with function declarations, this usage introduces a very bad programming habit, which is that developers tend to declare their functions only when they feel they need them. The result is code that mixes object declarations, function expressions and logic in something that obscures the core logic of a piece of code.
As a side effect of 2), code becomes much harder to read. If you would use proper function declarations and only var declarations for objects that actually will be variable in the code, it becomes far easier to scan the indentation line of code segment and quickly find the objects and the functions. When everything is declared as "var", you are suddenly forced to read much more carefully to find this piece of information.
As yet another nasty side effect of 2), as users get into the bad habit of only declaring their functions when they feel they need them, function expressions start showing up inside event handlers and loops, effectively creating a new copy of the function object either each time an event handler is called or for each turn in the loop. Needless to say, this is bad! Here is an example to show what I mean:
var myList = ['A', 'B', 'C'];
myList.forEach(function (element) {
// This is the problem I see.
var myInnerFunction = function () {
// Code that does something with element.
};
};
So to sum up, at least in my view, the only situation in which it is fair to use something like:
var myFunction = function () {
// Nice code.
}
is when your logic intends to change the myFunction reference to point at different functions during execution. In that situation myFunction (the variable) is something that is variable in the code, hence you are properly informing a different programmer of your intents, rather than confusing him/her.
With this background in mind, I ask my question again. Have I missed something central about function expressions (in the context described above) in which they provide any benefit over function declarations?
In Javascript, I have seen three different ways to define a function.
Conventional style:
function foo()
{
//do something
}
New Js Ninja Style
var foo = function(){
//do something
}
DOM specific style
window.foo = function(){
//do something
}
What question is,
What is the difference between the above three? And which one should I be using & why?
The first one is function declaration. It is hoisted (you could use it anywhere inside current scope).
The second one is a variable definition using anonymous function. Variable is hoisted, assignment stays in place. The function may not be used until the line where you assign it.
The third one is assigning a global method. Similar to the second one, although works with global object, which is not good.
Yet, you could think about the fourth alternative(named function expression):
var foo = function bar(){ //do something }
Here, bar will be available only inside itself, which is useful for recursion and not churning current scope with it.
You are selecting any approach based on your needs. I'd only vote against the second approach, as it makes function behave like a variable.
As soon as you mention both the second and the third option, I'd like to remind that polluting global object is considered bad practice. You'd better think about using self-executing anonymous functions to create separate scope, e.g.
(function(){
var t = 42; // window.t still does not exist after that
})();
I suppose you may find a more detailed article on JavaScript Scoping and Hoisting useful.
First, see Javascript: var functionName = function() {} vs function functionName() {}.
Then we get to the difference between var foo = and window.foo =.
The first is a locally scoped variable which is nice and lovely (unless it is done in the global scope). The second is a an explicit global, which has all the usual issues of globals (such as likelihood of conflicting with other code).
I am attempting to declare a function outside of anonymous function but still have acess to all of the anonymous functions variables
Below is demonstrating what I'm talking about.
I just need to get rid of eval.
//Used to determine where the variable is being stored
var variableScope = "global";
(function(window){
var variableScope = 'insideFunction',
appearingToBeGlobalFunction = function(){
alert("This Function appears Global but really isn't");
};
window["addFunction"]=function(funName,fun){
//window[funName] = fun; Doesn't work
eval("window[funName]="+fun+";");
}
})(window);
addFunction("alertTest",function(){
alert(variableScope);
appearingToBeGlobalFunction();
});
//should alert "insideFunction" and "This Function appears Global but really isn't"
alertTest();
Edit: The goal of this question was to ultimately keep the global scope clean from tons of variables, but still have the convenience of accessing, set and calling as if they were global. I have concluded there is a way to doing what I'm after but it requires a deprecated functionality in javascript.
Here is some example code showing how to accomplish the above without eval.
This article discusses how to use "with".
var variableScope = "global";
var customScope = {
variableScope : 'insideFunction',
appearingToBeGlobalFunction : function(){
alert("This Function appears Global but really isn't");
}
};
function alertTest(){
with(customScope){
alert(variableScope);
appearingToBeGlobalFunction();
}
};
//should alert "insideFunction" and "This Function appears Global but really isn't"
alertTest();
You can't get rid of eval and still expect it to work. That's the only way to take a look at members of the scope after it's been "closed." I've messed around with something similar in the past, but I would never actually use it anywhere. Consider an alternate solution to whatever you're trying to accomplish.
eval("window[funName]="+fun+";");
Oh dear Lord.
The reason this “works” is that you are converting the function fun (alertTest) into a string to put it in the eval argument.
It happens that in most desktop browsers, a native JS function's toString() result will be a string that looks like a function expression containing the same code as the original declaration. You're turning a function back into a string and re-parsing that string in the context of the new enclosing function, so the new function value is the same code but with a different closure.
However, it is not required that Function#toString work like this, and in some cases it won't. It is not safe to rely on function decomposition; avoid.
You can certainly only do this kind of horrific hackery using eval, although there is no reason the window[funName]= part has to be inside the eval. window[funName]= eval('('+fun+')'); would work equally well (badly).
I am attempting to declare a function outside of anonymous function but still have acess to all of the anonymous functions variables
Whyever would you do something crazy like that?
you could force the variables to be in the global scope eg instead of var variableScope = 'insideFunction' you use window.variableScope = 'insideFunction'
The goal of this question was to ultimately keep the global scope clean from tons of variables, but still have the convenience of accessing, set and calling as if they were global. I have concluded there is a way to doing what I'm after but it requires a deprecated functionality in javascript.
Here is some example code showing how to accomplish the above without eval.
This article discusses how to use "with".
var variableScope = "global";
var customScope = {
variableScope : 'insideFunction',
appearingToBeGlobalFunction : function(){
alert("This Function appears Global but really isn't");
}
};
function alertTest(){
with(customScope){
alert(variableScope);
appearingToBeGlobalFunction();
}
};
//should alert "insideFunction" and "This Function appears Global but really isn't"
alertTest();
Taking the jQuery framework for example, if you run code like this:
$(document).ready(function init() { foo.bar(); });
The stack trace you get in Firebug will look like this:
init()
anonymous()
anonymous([function(), init(), function(), 4 more...], function(), Object name=args)
anonymous()
anonymous()
As you can see, it's not very readable, because you have to click on each function to find out what it is. The anonymous functions would also show up as (?)() in the profiler, and they can lead to the "cannot access optimized closure" bug. It seems to me that these are good reasons to avoid them. Then there's the fact that ECMAScript 5 will deprecate arguments.callee in its strict mode, which means it won't be possible to reference anonymous functions with it, making them a little less future-proof.
On the other hand, using named functions can lead to repetition, e.g.:
var Foo = {
bar: function bar() {}
}
function Foo() {}
Foo.prototype.bar = function bar() {}
Am I correct in thinking that this repetition is justified in light of the debugging convenience named functions provide, and that the prevalence of anonymous functions in good frameworks like jQuery is an oversight?
I agree there are certain downsides to using anonymous methods in JavaScript/EMCAScript. However, don't overlook how they should be used. For simple one liners that you want to pass to another function, they are often excellent.
I found the answer to my question in this very informative article. Firstly, it turns out that I was right about named functions being more desirable, but the solution is not as simple as adding identifiers to all anonymous functions. The main reason for this is JScript implementing function expressions in a very broken way.
Secondly, there is a distinction between function statements and expressions. An anonymous function is just a function expression with the identifier omitted, and adding an identifier (naming it) wouldn't make it a statement (except in JScript, which is why it's broken). This means that all of the other answers were off mark.
But for me anonymous functions are more readable in the source code, because I am sure they are only used there.
Anonymous functions are very convenient. A better fix to this problem, instead of naming the functions, would be if firebug told you on which line in which file the anonymous function was created.
init()
anonymous() // application.js, line 54
anonymous() // foo.js, line 2
And the stack trace is the only place where anonymous functions are a problem imo.