“var functionName” vs “function functionName”
stackoverflow.com
stackoverflow.com
function make_dot_product(dim) {
if (dim === 3) {
var dot = function(a,b) {
return a.x*b.x+a.y*b.y+a.z*b.z
}
} else if (dim === 2) {
var dot = function(a,b) {
return a.x*b.x+a.y*b.y
}
}
return dot
}
vs. function make_dot_product(dim) {
if (dim === 3) {
function dot(a,b) {
return a.x*b.x+a.y*b.y+a.z*b.z
}
} else if (dim === 2) {
function dot(a,b) {
return a.x*b.x+a.y*b.y
}
}
return dot
}
The second case is erroneous, as it will always return 2-dimensional dot function (even if you call make_dot_product(20)). The is because function nameSpace() is defined at parse time, so inside the make_dot_product scope, two instance of dot functions are created, with the second overwriting the first. If we use var f = function() {...} this can be avoided. function make_dot_product(dim) {
if (dim === 3) {
return function(a,b) {
return a.x*b.x+a.y*b.y+a.z*b.z
}
} else if (dim === 2) {
return function(a,b) {
return a.x*b.x+a.y*b.y
}
}
return null;
} function make_dot_product(dim) {
return (dim === 3) ? dot3 : dot2;
function dot3(a,b) {
return a.x*b.x+a.y*b.y+a.z*b.z
}
function dot2(a,b) {
return a.x*b.x+a.y*b.y
}
} function make_dot_product(dim) {
var dot;
if (dim === 3) {
dot = function(a, b) {
return a.x * b.x + a.y * b.y + a.z * b.z;
};
} else if (dim === 2) {
dot = function(a, b) {
return a.x * b.x + a.y * b.y;
};
}
return dot;
}
This also makes it clearer what happens if neither dim is neither 2 nor 3.That said, it is cleaner to only 'var' each variable once, to suppress this confusion.
var a = function(b) {
if (b === 0) {
return true;
}
return a(--b);
};
var b = a;
a = function() { return false; };
b(5);
As an alternative, you should go var a = function a2(b) {
if (b === 0) {
return true;
}
return a2(--b);
};
var b = a;
a = function() { return false; };
var a2 = function() { return false; };
b(5);
Perhaps counterintuitively, a2 doesn't leak into the containing scope, which makes it safe to use within the function it declares.Some older browsers fuck this up though, IIRC.
it's one of my main tools to fight the callback pyramid of doom.
use named functions, place them below the code that uses them.
all flat.
function bunchOfAsyncThings(callback) {
var function1, function2;
function1 = function (callback) {
// do stuff here, then do callback
function2(callback);
};
function 2 = function (callback) {
// done with everything
callback();
};
function1(callback);
}
(Edit: formatting) {
f();
var a = 3;
function f() {
console.log(a);
}
}
That will print "undefined" because the entire function f() is hoisted and callable in the first line, but the variable a has not yet been assigned the value. That's not a race condition (those are related to timing in concurrent systems) but is certainly the sort of counter-intuitive visibility that makes me prefer to use function expressions most of the time.I don't do it as much as i would with plain js, because the function definition feels less awkward, but I do still prefer named functions over anonymous ones. even if the name only exists in the local scope.
// this is all the code that is used,
var _changes = follow(couchOpts);
_changes.on('change', onChange);
_changes.on('error', onError);
_changes.resume();
// from here is just named functions
function onChange(data) {
_changes.pause();
save(data.seqId, saveFn);
}
function saveFn(err, entity) {
if (err) { return console.log(err); }
_changes.resume();
}
function onError(err) {
console.log(err);
}My POV is you simply shouldn't be putting a function in a variable, it's supposed to be reusable code and you've just made it's position a completely pointless dependency as well as obfuscated the code's meaning.
A named function is clearly supposedly immutable, reusable code (save monkey patching). A function in a variable looks like you might change it.
I want to stress, there are very good reasons to assign a function to a variable. There are also very good reasons to declare a function within the scope of another too. But they are few and far between.
To willy nilly declare functions like they're variables. Bizarre. Perhaps someone who does it can explain what it gains them? The place I first saw it was in Crockford's the Good Parts, but he seems to have stopped doing it when you go look at his code.
Binding functions to variables however does highlight the fact that functions are first-class values in JavaScript and can be locally scoped, passed to other functions and can be operated on. Functions in Javascript are not the same as functions C or Java and don't need to pretend to be similar.
If you want to prevent a function binding to be changed, use es6's const and don't pretend that function declarations helps you with that.
1. Anonymous functions assigned to variables. These make debugging a nightmare. Some (possibly all) versions of IE reports something like "error on line 0" when it occurs in such a function, so you really have no idea what went wrong.
2. Accidental closure creation.
Both of these are avoided by just declaring your functions statically. If you want to create an object, you can still assign a static function to a property, e.g.:
function foo() { ... }
Foo.prototype.foo = foo;
Back when I used to primarily write JavaScript, and compatibility with things like Netscape and IE3 were a concern, I'd write all my code roughly like that and just namespace the functions if they are for a particular class, e.g.: function className_functionName() { ... }
className.prototype.functionName = className_functionName;
This guarantees maximum compatibility with very old versions of JavaScript/JScript, runtime efficiency (functions get evaluated at parse time not runtime, also guaranteeing only one copy of the function code is ever created) and no possibility of accidentally creating a closure where you don't want to (which can lead to memory leaks).The downside is that it it makes your JavaScript code look more like C++ code that Java, and even less like Ruby. It also requires a tiny bit more typing, and we all know how much programmers hate typing.
Don't write JS in that style when compatibility with ancient browsers is not an issue. Hard to read, maintain and understand.
Would you also object to
var functions = { a: function() {}, b: function() {} }
or var functions = [ function() {}, function() {} ]
?in those cases we're creating a storage structure and loading it with functions - a single variable is just another case of the same.
What about
var log = console.log || function(msg) { };
?The function foo() {} declaration syntax in JavaScript is a syntactic hack that uses function hoisting to allow functions to be used 'before' they are declared. All it does is turn into a var foo = function foo() {} at the top of the current scope.
But because of var scope, variables can also be used before they're declared, so often you don't need it anyway:
var a = function() { return b(); };
var b = function() {};
a();
I suspect people who strongly prefer var foo = function() {} over function foo() {} are people who have internalized the idea of functions as data. I'd hesitate to say 'functional programmers', but perhaps 'functional JavaScripters' is valid.As for "There are also very good reasons to declare a function within the scope of another too. But they are few and far between" - the benefits of closure over parent function scope are incredibly powerful - I don't think they are few and far between at all. I tend to declare pretty much all my functions inside a function using the module pattern:
(function() {
var x = 0;
var f = function() { return x++; };
window.makeObj = function() { return { id: f() }; }
})();In the end, if you think normal function declaration is a "syntactic hack" we're simply not going to agree.
I've used a fair few different languages and to me the distinction between a plain old function and a closure is a useful distinction that helps me read the code quicker.
By declaring it as a variable, you're making it hard to decide which it will be as well.
And deeply coupling code for no good reason. This is the other thing I can't understand. I can't even MOVE your function without worrying about side effects.
On a side note, my original post is going up and down in votes like a yo-yo.
If it's a pattern you haven't used, I can certainly understand being wary of it at first. But being wary is different than being prescriptive. There is always more to learn.
I think the difference here is that you see
function Foo() {
...
}
as a 'normal' function declaration. I see it as a syntax which hides the truth - that that is actually putting var Foo = function Foo() {
..
};
at the top of its scope. It's a special syntax for the special case of "I want this function to have this name and be bound to a variable with the same name for the whole of its enclosing scope". But JavaScript permits me to do lots of OTHER things with functions, and pretending it can't doesn't help me write better JavaScript code.functions are the ONLY way in JavaScript to restrict the scope of a name. How can you talk about the risks of moving things if you aren't even taking advantage of JavaScript's only mechanism to create safely encapsulated name scopes?
I'm talking about simple code structure.
You need a function.
Do you put it in a var or not.
I have nothing against closures or namespaces or object declaration or many of the million other things you can twist objects in js to do.
What I hate is this:
var checkValid = function(item) {
return item!= blah;
}
When it should be: function checkValid(item) {
//blah
}
Stop accusing me of a position you've made up in your head. projectname = {
A_CONSTANT: ...,
someFunc: function(...) {
},
...
lastFunc: function(...) {
}
}
Basically, JSON layout but with the functions in the resulting namespace.Debugging & diagnostics for this layout in Firefox and Chrome is not a problem. As for IE, well, some things can't be fixed, I guess.
projectname = (function(){
self = {};
self.A_CONSTANT = ...;
self.someFunc = function(...){
};
self.lastFunc = function(...){
};
return self;
})();
I think that produces the exact same end result, but someone set me straight if I'm mistaken.My version is the "static method" version that requires the namespace and a dot before any function calls. I'm OK with that, unless I need a bunch of instances of something.
P.S. - the semicolons don't really do anything (other than make Doug C feel good), as JS is a line oriented language, and will complete statements when they "look done", semis or not. Think of semicolons in JS like colons in BASIC: they let you put a second statement on the same line.
How about simple closures:
function getCounter(){
var num = 0;
return function(){
return num++;
};
}
How about overriding default functions? This is a snippet from a codebase I'm working on right now: require(['helpers/user'], function(User){
// hack because we are not using layout.master
User.isLoggedIn = function(){ return global.userInfo.id > 0; };
});
How about re-using some code in a function? Another snippet from the same code, where self can change based on context: var inCart = function(){
$(self)
.addClass('disabled')
.text('In Cart');
};
if (Cart.isMixIdInCart(results['mixId'])){
inCart();
}else{
$('.widget .purchase').on('click', function(){
$('.widget .purchase').text('Adding');
Cart.addToCart(results['mixId']).done(inCart);
return false;
});
}
These are simply different ways to use closures, but that's part of the benefit of using anonymous functions. function doSomething() {
// do stuff
return this;
}
However, the `return this` line doesn't really have anything to do with the core of what the method is supposed to do. Its largely an implementation detail.I feel the method looks much better like :
var doSomething = fluent(function() {
// doSomething
});
The fluent function handles the `return this;` so it doesn't obscure the core method.It is one of most beautiful aspects of javascript that it enables you to build functions from other functions.
This is my other beef with ignorant javascript programmers, so stuck in the past. Most other languages now do this, and, shock, horror, do it better than js which is horribly behind the times.
function functionName()
will show up in a stack trace with a name, whereas the other won't.You can also do this:
var f = function functionName() { }Take a look at http://jsfiddle.net/2LsSg/.
window.onload/g@http://fiddle.jshell.net/2LsSg/show/:23:5
window.onload/f@http://fiddle.jshell.net/2LsSg/show/:26:5
@http://fiddle.jshell.net/2LsSg/show/ line 29 > eval:1:1
window.onload@http://fiddle.jshell.net/2LsSg/show/:29:1
(I guess jsfiddle wraps the JS code in a window.onload handler, which makes this a bit more ugly)Is it really that much work to name your functions?
var MyObject;
(function() {
var staticPrivateVariable;
MyObject = function(opts) {
// Do Initialization Stuff
};
MyObject.prototype.publicInstanceFunction = function(opts) {
// Do instance stuff
};
})();
var Namespace;
(function() {
var staticPrivateVariable;
Namespace = function(opts) {
// Do Initialization Stuff
};
Namespace.publicFunction = function(opts) {
};
function privateFunction(opts) {
// Do some private stuff
}
})(); var functionName = function() {
// whatever
}
I had no idea there were other ways to write a function. I still don't understand what the benefits or drawbacks are of each method. Maybe I haven't made it that far yet. But I literally have no idea what most of you are talking about in this thread. I feel like I visited a post written in chinese.The scope of learning to code seems overwhelming. Finding small bugs in syntax and design is stressful. What I'm supposed to learn (language, style, syntax, frameworks) seems to change faster than I can learn it. I wish I would have started all of this earlier ... like when I was 10.
I think what might help you is thinking of programming languages as foreign languages. They have their own vocabulary and grammar. So right away, let that take the pressure off in terms of how quickly you are picking it up. Some people can pick up foreign languages easily. Others can pick up programming languages just as fast. But even if you don't have a natural knack for it, with some persistence practice and time, you will get there.
Also, remember that the person you are talking to in your new language (the computer) is the biggest grammar nazi you have ever met. And they will refuse to acknowledge you unless you use the proper form exactly right. So you can't get away with just memorizing "Could you please tell me where is the bathroom?" because one day you'll accidentally say "Could please tell me bathroom", and your previously helpful foreign friend will completely blow you off. What that means is I think it will be easier if you try to really understand every part of the line you are writing: What is a function. What is "var". WHY do you use var sometimes, and sometimes not, and what is the difference. What is the crazy jQuery syntax all about, with $'s, and parenthesis, and callbacks, etc.
It will take you more time up front, but will lead to fewer frustration in the long run.
Good luck!
function a() {}
// or
var a = function() {}
// or
var a = function a() {}
// or
obj.prototype.a = function() {}
// or
obj.prototype.a = function a() {}
There is little difference in the function declaration. The difference is if you named it or not.The reason you have to be careful with the var a = function() {} forms is because variables are hoisted. So while the function will exist, your variable will not point to that function until the assignment happens.
Definitely don't waste your time chasing the latest and greatest. Most frameworks are fads — that's why they go in and out of fashion so quickly. Once you solidly understand the basics, and once you have gained some experience (you probably need a year or so), you'll know enough to evaluate libraries and frameworks efficiently.
Build something using the tools you already know. Don't use too many libraries. Don't copy in code from StackOverflow which you don't understand. Don't listen to know-it-alls who respond to your questions with "why would you ever want to do that?" Just code up a solution to your current problem, and move on. You'll be a good hacker before you know it.
PS: I do suggest you learn to program outside the web domain. The web is unusually beginner-unfriendly because (1) you have to keep dealing with the browser-server stateless request-response fundamental design, and (2) the browser and the DOM are pretty confusing concepts.
What's worked for me: use whatever meager skills you have to work on a real project that you find interesting. Not something that can hurt people if it goes wrong, but something you care about. Concentrate on the user experience. Eventually, you'll learn better ways to do things as you need to.
I made http://asoftmurmur.com
If you want a laugh, look at the source (the javascript at the bottom of the main index). It's probably the worst JS I've ever seen, but I concentrated on the user experience and I'm pretty happy with how that worked out. I'm now building an Android version and the source is a thousand times more elegant and concise. In the grand scheme of things, I'm sure it's still awful, but that's fine, so long as the user experience is good. Next time the code will be better.
Build something real. When you run into a problem you can't solve by yourself, ask for help. This will naturally create a narrow but ever-expanding scope in the face of a limitless quantity of knowledge. I don't know anything about programming, but that's what's worked for me so far.
The "at a" is what we're looking for. I develop largely in Chrome; its been doing this for months, at least.
It also works in IE11 (the only version I have readily available), Firefox, and Safari.
And the trailing underscore is to placate some version of IE. Or something. I can't keep it all strait when I'm just out of bed.
Also, functions have names.
var funcName = function () {};
funcName.name; // ""
function func2() {};
func2.name; // "func2"
Thus, anynomous functions are truly anonymous whether or not they're assigned to a variable. `func2` can be assigned to a variable too. It'd retain its name (`func2`). Object.prototype.method = function Object$method() { ... }
an interesting mixture of both method.namespace.functionName = function() { }
I'm not talking about performance here, but from a sheer maintainability nightmare that JS creates. If you care about this, don't let your functions be unbound.
The only reason to store a function in a var is because it is a closure.
And in a way, a closure is data encapsulation in a totally non OO way.
I'd rather use Asychronous Module Definitions: http://requirejs.org/docs/whyamd.html
functionOne = function() {
// Some code
};(i.e. without the var) is represented same as:
function functionTwo() {
// Some code
}is it?
Without the "var" keyword, you just created a global variable rather than one restricted to your local scope.