I'm new to javascript and have picked up an application developed by another team recently.
In this program in one place where they declare several variables at once there is a missing comma like:
var me = this,
missing = this.missingComma
grid = something.Something;
What if any are the consequences of there not being a comma after the second entry. The relevant bit appears to work when just running it. The code has no tests and since it's javascript I cant compile it, also I dont really know what its supposed to do so unfortunately 'not falling over' is currently my best guess at 'does what its supposed to do'!
Why does it work? Isn't this a syntax error?
In JavaScript the semi-colons aren't required to indicate the end of a line. A linebreak is sufficient to indicate that the next line is a separate statement rather than a continuation of the previous line of code (as is the case when you use the comma to indicate multiple variables).
Your code is essentially the same as this:
var me = this, missing = this.missingComma;
grid = something.Something;
Since that declares the grid variable without the var keyword, you'd end up with grid being created in the global, rather than the current, scope. That's generally something you want to avoid but it's not going to be the end of the world if it does happen - in this case it may even be intended (though I'd guess not).
Javascript is ubiguitous with a a lot of freedom ;)
Maybe it helps you to understand some peculiarity of JS if you read some additional info about semicolons, commas and newlines in Javascript:
http://www.codecademy.com/blog/78-your-guide-to-semicolons-in-javascript
For the sake of readability, I would suggest you to use the classic approach, anyway.
var me = this;
var you = that;
or at least
var me = this, you = that;
For the rest, I think that Anthony Grist has brought it to the point.
Well even though in javascript the semicolon is not required it is a must now a days, because if you want your JavaScript to get minimized, it must have all semicolons. Minimization puts your complete JavaScript in one line... replacing long variable names with short ones, etc.
On the other hand... back to you question.
If you declare your var inside a JavaScript "namespace" (actually an object) then all the variables are "private" and you could choose to make the ones "public" by using the reveal pattern.
This is a good practice, else all you variables are declared on the windows scope... which actually can then be overwritten by any other part of your page that uses the same variable name, even if you thought it was completely independent.
So you could actually do something like this :
var MyNamespace || {}
// this delcares an object MyNamespace only if it doesn't exists yet
MyNamespace.Logic = function(){
var self = this,
myPrivateVariable = "Hello",
self.myPublicVariable = "World",
self.printHello = function(){
alert(myPrivateVariable +' ' +self.myPublicVariable );
};//this semicolon closes the var statement
};
Now you can use somehwer on you page folowing logic
var newInstanceOnMyLogic = new MyNamespace.Logic()
This is equivalent of writing
var newInstanceOnMyLogic = new window.MyNamespace.Logic();
But your variables myPrivateVariable and myPublicVariable are no longer on the windows context and can't be overwritten
Now if you write something like
alert(newInstanceOnMyLogic.myPublicVariable);
you'll get a "World"
But
alert(newInstanceOnMyLogic.myPrivateVariable );
you'll get an undefined
and
newInstanceOnMyLogic.printHello();
will get an alert of "Hello World"
Related
There are similar questions here but they didn't really answer my questions.
So I am curious why we can't declare the same variable twice in Java?
for example:
int a = 4;
int a = 6;
this won't really work in Java.
However in javascript, this actually works:
var a = 1;
var a = 2;
In javascript, people said that the declaration immediately got moved to the start so that it became like this:
var a;
a = 1;
a = 2;
The simple, obvious answer is because the compiler doesn't let you. But now let's go a step further - why would this be desired?
The reason here is that declaring a variable twice is a sign of a mistake. It usually means one of three things:
Your variable names are not specific enough. Perhaps you used int length twice and it barks at you. You probably should make your name more specific to what it holds the length of, for example int originalLength and int extendedLength when copying an array or something.
Your method is too long. Why is your method so long that you need two of the same variable? Chances are you're duplicating code, so consolidate that into a method.
You haven't really thought out your method. This is sort of an extension of number 2, but the truth is you should decide what a method does before you write it. If you're adding a variable that already exists, it probably means that you haven't decided exactly what this method is doing.
Each of those is a major code smell, and is probably the source of bugs down the road. (And not far down the road!) In each of the cases, allowing you to declare a variable twice is going to cause ambiguity that would have been prevented if it stopped you from compiling.
Now, does this mean there aren't cases where it might be nice? Sure. There might be. Maybe you've covered all your bases and you're absolutely sure it's okay to reuse that variable. In that case, just reassign it instead of redeclaring it. Personally, I'd advise against that, but it's your foot to shoot if you want to. :)
You can use the same variable name if the scopes don't overlap, for instance i could have a variable in a private method called "var1" and then in another method have the same thing, these two would not conflict
However since everytime i use "int var1" in the same scope, java is re-declaring the variable, it wont allow it, as it's a conflicting variable name, whereas in java script the declaration happens once, as it's weakly typed
now it has been rectified or improvised in javascript too with the new let keyword
if you try to intialize the same variable name more than once it will throw an error
let a = 4;
let a = 5;
will throw an error in ES6
Considering this:
var getToDaChoppa = false;
var warIsHell = function() {
// Write your do/while loop here!
do {
console.log("I can't my legs omg my LEGS");
} while (getToDaChoppa);
};
warIsHell();
and this
var getToDaChoppa = function() {
var getToDaChoppa = false;
do {
console.log("I can't my legs omg my LEGS");
} while (getToDaChoppa);
};
getToDaChoppa();
I really like to know which piece of code is better from a technical standpoint. (Lower memory usage, garbage generation, etc). I'm pretty n00b to js, but I want to make sure I'm writting the best possible code.
From my limited experience the second snippet will generate double garbage than the first one, but in the other hand, the first one uses double the memory than the second one, so I was wondering what is the best approach here. Ofc if you need to swing around variable values, ¿I understand first one is more versatile?, but I cannot fully comprenhend the pros / cons of both methods.
Any little explanation will be of great help o:)
The main difference I see between your two functions is that the first one uses a global (or at least external) variable while the second one use a local variable.
Then the rule is simple : don't declare a variable in an external scope if you don't use it in that scope. Always declare your variables in the most internal scope. This makes the code more readable and limits the risks of collision. Trying to reduce the garbaging by making it external is terrible practice and useless unless, in a very specific case, you proved by profiling you have a problem and it is solved that way (then... I won't probably trust you...).
A second rule would be : don't shadow variables if possible. Shadowing the name of the function with a boolean variable is very confusing.
Here's a "fixed" code :
var getToDaChoppa = function() {
var finished = false;
do {
// some code, which hopefully will at some point set finished to true
} while (!finished); // you wanted a !, here, no ?
};
getToDaChoppa();
I would say that the second approach is better simply because you're keeping the condition variable inside the function scope, thus not polluting the global scope.
Also, don't name the variable with the same name as the function.
i have a simple question about caching, this kind of confuses me lol
Im not sure if it depends on if your using handlers or not but...
is there any difference between these two?
var $something = $('.something');
or
var something = $('.something');
and also, is it possible to do this (depending on the correct way)
var something = $('something'),
somethingElse = $('somethingelse');
or this way
var something = $('something');
var somethingElse = $('somethingelse');
just want to be sure im heading in the right direction.
It's been bothering me. I've seen it done both ways actually, but i don't know which is right, or if either are wrong. I'm sure someone knows for sure though :)
Prefixing variables with $ is only used to remind the programmer (or others) that the variable holds a jquery object. It isn't a 'javascript thing' and does not provide any additional functionality. It's a good idea though :)
All the code you posted is valid.
It's your choice. Many people (including myself) prefix variables with $ to indicate that the variables represent jQuery objects (because $ is shorthand for jQuery). If you think it helps you along the same lines, then you're free to prefix your variables as such.
Declaring multiple variables comma-separated with a single var keyword is legal JavaScript.
What are the differences and/or advantages, if any, of using commas when declaring a group of variables rather than semicolons.
For example:
var foo = 'bar', bar = 'foo';
versus
var foo = 'bar';
var bar = 'foo';
I know that if you specify the var keyword on the first variable in the first example it persists across all of the variables, so they both produce the same end result regarding scope. Is it just personal preference, or is there a performance benefit to doing it either way?
No performance benefit, just a matter of personal choice and style.
The first version is just more succinct.
Update:
In terms of the amount of data going over the wire, of course less is better, however you would need a hell of a lot of removed var declarations in order to see a real impact.
Minification has been mentioned as something that the first example will help with for better minification, however, as Daniel Vassallo points out in the comments, a good minifier will automatically do that for you anyways, so in that respect no impact whatsoever.
After reading Crockford and others, I started to chain my variables with comma exclusively. Then later, I really got annoyed by the Chrome DevTools debugger that wouldn't stop at variable definitions with comma. For the debugger, variable definitions chained with comma are a single statement, while multiple var statements are multiple statements at which the debugger can stop. Therefore, I switched back from:
var a = doSomethingA,
b = doSomethignB,
c = doSomethingC;
To:
var a = doSomethingA;
var b = doSomethignB;
var c = doSomethingC;
By now, I find the second variant much cleaner, not to mention its advantage of solving the debugger issue.
The "less code through the wire" argument is not persuasive, as there are minifiers.
I prefer the var-per-variable notation:
var a = 2
var b = 3
because the other comma-instead-of-another-var notation have these three shortcomings:
1. Hard to maintain
Consider this code:
var a = 1,
b = mogrify(2),
c = 3
But hey, what does the mogrify do? Let's print b to find out:
var a = 1,
b = mogrify(2),
console.log(b)
c = 3
breaks stuff
2. Hard to read
The var in the begging of the line clearly communicates that there will be a new variable initiated.
var get_all_unicorn_promise = db.get_all_unicorns((unicorn) => {
unicorn.legs.map((leg) => {
leg.log('yes')
})
}).sort(),
c = 3
What the hell is the c = 3 doing there right?
3. Not consistent
Consider this:
var a = 1,
b = 2,
c = 3
With var-per-variable every declaration follow the same structure. With comma-instead-of-another-var the first variable is declared in different way than others. If you decide to, say, move the first variable inside a for cycle, you will have to add var to the middle of declarations
Other than preference, it seems like majority of notable projects use the var-per-variable notation
I agree with the other answerers that this is mainly a matter of personal style. But to bring an "Authoritative" opinion into the discussion, this is what Douglas Crockford says on the website of the popular JSLint tool:
But because JavaScript does not have block scope, it is wiser to declare all of a function's variables at the top of the function. It is recommended that a single var statement be used per function. This can be enforced with the onevar option.
As others have noted, it is a style preference. JSLint might tell you to only have one var per function (if you use the "Good Parts"). Thus if using JSLint to check your code (not a bad idea, IMHO), you'll end up using the first format more than the latter.
On the other hand, the same author, Douglas Crockford, says to put each variable in its own line in his coding conventions. So you may want to uncheck the "All one var per function" checkbox in JSLint if you use it. ;-)
I don't think there's any noticeable difference, as far as I'm concerned it's just personal preference.
I hate having multiple var declarations so I usually do:
var
one
,two
,three
,four
;
As it's shorter and arguably more readable, no var noise to look at.
Since I don't see any references to it, here is a link to the ECMA-262 specification, which is the underlying spec for JavaScript. The grammar from that page says:
12.2 Variable Statement
Syntax
VariableStatement :
var VariableDeclarationList ;
VariableDeclarationList :
VariableDeclaration
VariableDeclarationList , VariableDeclaration
VariableDeclarationListNoIn :
VariableDeclarationNoIn
VariableDeclarationListNoIn , VariableDeclarationNoIn
VariableDeclaration :
Identifier Initialiseropt
VariableDeclarationNoIn :
Identifier InitialiserNoInopt
Initialiser :
= AssignmentExpression
InitialiserNoIn :
= AssignmentExpressionNoIn
What you can glean from this is using commas or not doesn't matter. Either way, it ends up being parsed as a VariableDeclaration and is treated exactly the same. There should be no difference to how the script engine treats the two declarations. The only differences would be ones already mentioned in other answers - saving more space and practically immeasurable differences in the amount of time it takes to apply the grammar to find all the VariableDeclarations when the script is compiled.
The first saves a few characters--so there is a very small saving in terms of the JS filesize and therefore bandwidth consumption. The only time this would become noticable would be in extreme cases.
I prefer the second version (each has its own var). I think that's because I come from a C++ background. In C++, you can declare variables like you do in your first example, but it is frowned upon (it easily leads to mistakes when you're trying to create pointers that way).
If you are minifying your javascript, there is a fairly large benefit:
var one, two, three, four;
becomes
var a, b, c, d;
Where as
var one;
var two;
var three;
var four;
becomes
var a;
var b;
var c;
var d;
That's an additional three instances of var, which can add up over time.
See The "A List Apart" article series "Better Javascript Minification" Part 1 and Part 2
What's the shortest way (characters) of creating a "new function" alias.
Basically this is for code golf and minifying code beyond reason.
So when you usually would write:
a=function(a,b,c){return a+b+c;}
You could write something like (also let's abstract return keyword as well with global variable R):
a=$("a,b,c","R=a+b+c")
a=$(a,b,c){R=a+b+c}
(Not sure if the second one is possible.)
For the first example the best I've come up with is:
$=function(a,b){return new Function(a,"R=0;"+b+";return R")}
Both the sizes (usage, declaration) matter but usage size is more important.
I don't think new Function() is of viable use for most functions even without performance concerns because unlike function() {} no closure is created. The compiled function will only have access to its own local scope and the global object. Think about that for a second. Javascript without closures is like Java without classes or C without pointers. Clearly everything would break.
Anyways, if you only intend to use this alias for short lambada like expressions that don't need clousers, one obvious way to make things even more terse is to leave off the parameters deceleration. Simply assume that a = arguments[0]; b = arguments[1]; etc...
$=function(b){return new Function('a,b,c,d,e,f,g,h,i,j', b);};
Another way would be to automatically return the value of the last expression, instead of needing it to be explicitly declared
$=function(body) {
return function(a,b,c,d,e,f,g,h,i,j) { return eval(body); };
};
Horrifying isn't it? This works because eval()...well it returns the value of the last evaluated expression. No return needed. Of course this method is an even bigger hit to performance, as the code in body is reevaluated each time the function is called, while with new Function the code is (or should be) only compiled once.
Anyways performance be dammed, with the previous method your function declaration is down to this
var myeyes = $('a+b+c');
alert(myeyes(1,2,3)); //6
Purdy huh? Still, I think it would look better like this
'a+b+c'
Looks like a string yes? Well...it is a sting, but in the hands of the right function, it could be evaluated as if it were a full on function literal
//Lets just assume that IE does not exist mmkay?
var funcs = ['map', 'filter', 'every', 'some'];
for (var i=0; i<funcs.length; i++) {
(function() {
//Store original function
var name = funcs[i]
var _super = Array.prototype[name];
Array.prototype[name] = function() {
//$ !== jQuery
if (typeof arguments[0] == 'string') arguments[0] = $(arguments[0]);
return _super.apply(this, arguments);
};
}());
}
Now you can write
[1,2,3,4,5].map('a*a');
instead of
[1,2,3,4,5].map(function(a){return a*a;});
which is even better than Firefox's Expression Closure
[1,2,3,4,5].map(function(a) a*a);
Try it out here: http://jsbin.com/iyogu3/edit
If only we could actually write function expressions like this without calling upon the eval monster. Really, one of my main gripes with Javascript syntax is the requirement to spam function(){} throughout your code. Some kind of shorthand function literal syntax (not the aforementioned half-assed expression closure) that was interpreted the same as a regular verbose function literal would go a long way to making my code look a little less ridiculous. And it might help minifying a tiny bit as well.
For simple expressions, you could use:
function L(a,x){return new Function(a,'return '+x)}
Usage:
n=L('a,b,c','a+b+c');
You might get milage out of something silly like:
eval("t=Fa+b};t(1,2)".replace("F", "function(a,b){return "))
Here's a variant that has a larger overhead but saves one character per function definition.
"#" will be replaced with "return ".
$=function(a,b){return new Function(a,b.replace(/#/g,"return "))}
a=$("a,b,c","#a+b+c")
Your code:
a=function(a,b,c){return a+b+c;}
Shortened code:
a=(a,b,c)=>a+b+c
The shortest function declaration possible in js is 4 characters
Example: _=>1