var assignment and declaration using a single var and commas? [duplicate] - javascript

In JavaScript, it is possible to declare multiple variables like this:
var variable1 = "Hello, World!";
var variable2 = "Testing...";
var variable3 = 42;
...or like this:
var variable1 = "Hello, World!",
variable2 = "Testing...",
variable3 = 42;
Is one method better/faster than the other?

The first way is easier to maintain. Each declaration is a single statement on a single line, so you can easily add, remove, and reorder the declarations.
With the second way, it is annoying to remove the first or last declaration because they start from the var keyword and finish with the semicolon respectively. Every time you add a new declaration, you have to replace the semicolon in the last old line with a comma.

Besides maintainability, the first way eliminates possibility of accident global variables creation:
(function () {
var variable1 = "Hello, World!" // Semicolon is missed out accidentally
var variable2 = "Testing..."; // Still a local variable
var variable3 = 42;
}());
While the second way is less forgiving:
(function () {
var variable1 = "Hello, World!" // Comma is missed out accidentally
variable2 = "Testing...", // Becomes a global variable
variable3 = 42; // A global variable as well
}());

It's much more readable when doing it this way:
var hey = 23;
var hi = 3;
var howdy 4;
But takes less space and lines of code this way:
var hey=23,hi=3,howdy=4;
It can be ideal for saving space, but let JavaScript compressors handle it for you.

ECMAScript 2015 introduced destructuring assignment which works pretty nice:
[a, b] = [1, 2]
a will equal 1 and b will equal 2.

It's common to use one var statement per scope for organization. The way all "scopes" follow a similar pattern making the code more readable. Additionally, the engine "hoists" them all to the top anyway. So keeping your declarations together mimics what will actually happen more closely.

It's just a matter of personal preference. There is no difference between these two ways, other than a few bytes saved with the second form if you strip out the white space.

Maybe like this
var variable1 = "Hello, World!"
, variable2 = 2
, variable3 = "How are you doing?"
, variable4 = 42;
Except when changing the first or last variable, it is easy to maintain and read.

Use the ES6 destructuring assignment: It will unpack values from arrays, or properties from objects, into distinct variables.
let [variable1 , variable2, variable3] =
["Hello, World!", "Testing...", 42];
console.log(variable1); // Hello, World!
console.log(variable2); // Testing...
console.log(variable3); // 42

var variable1 = "Hello, World!";
var variable2 = "Testing...";
var variable3 = 42;
is more readable than:
var variable1 = "Hello, World!",
variable2 = "Testing...",
variable3 = 42;
But they do the same thing.

My only, yet essential, use for a comma is in a for loop:
for (var i = 0, n = a.length; i < n; i++) {
var e = a[i];
console.log(e);
}
I went here to look up whether this is OK in JavaScript.
Even seeing it work, a question remained whether n is local to the function.
This verifies n is local:
a = [3, 5, 7, 11];
(function l () { for (var i = 0, n = a.length; i < n; i++) {
var e = a[i];
console.log(e);
}}) ();
console.log(typeof n == "undefined" ?
"as expected, n was local" : "oops, n was global");
For a moment I wasn't sure, switching between languages.

Although both are valid, using the second discourages inexperienced developers from placing var statements all over the place and causing hoisting issues. If there is only one var per function, at the top of the function, then it is easier to debug the code as a whole. This can mean that the lines where the variables are declared are not as explicit as some may like.
I feel that trade-off is worth it, if it means weaning a developer off of dropping 'var' anywhere they feel like.
People may complain about JSLint, I do as well, but a lot of it is geared not toward fixing issues with the language, but in correcting bad habits of the coders and therefore preventing problems in the code they write. Therefore:
"In languages with block scope, it is usually recommended that variables be declared at the site of first use. 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." - http://www.jslint.com/lint.html#scope

Another reason to avoid the single statement version (single var) is debugging. If an exception is thrown in any of the assignment lines the stack trace shows only the one line.
If you had 10 variables defined with the comma syntax you have no way to directly know which one was the culprit.
The individual statement version does not suffer from this ambiguity.

I think it's a matter of personal preference. I prefer to do it in the following way:
var /* Variables */
me = this, that = scope,
temp, tempUri, tempUrl,
videoId = getQueryString()["id"],
host = location.protocol + '//' + location.host,
baseUrl = "localhost",
str = "Visit W3Schools",
n = str.search(/w3schools/i),
x = 5,
y = 6,
z = x + y
/* End Variables */;

The maintainability issue can be pretty easily overcome with a little formatting, like such:
let
my_var1 = 'foo',
my_var2 = 'bar',
my_var3 = 'baz'
;
I use this formatting strictly as a matter of personal preference. I skip this format for single declarations, of course, or where it simply gums up the works.

As everyone has stated it is largely preference and readability, but I'll throw a comment on the thread since I didn't see others share thoughts in this vein
I think the answer to this question is largely dependent on what variables you're setting and how they're related. I try to be consistent based on if the variables I'm creating are related or not; my preference generally looks something like this:
For unrelated variables
I single-line them so they can be easily moved later; I personally would never declare unrelated items any other way:
const unrelatedVar1 = 1;
const unrelatedVar2 = 2;
const unrelatedVar3 = 3;
For related things (utility)
If I'm creating new variables I declare as a block -- this serves as a hint that the attributes belong together
const
x = 1,
y = 2,
z = 3
;
// or
const x=1, y=2, z=3;
// or if I'm going to pass these params to other functions/methods
const someCoordinate = {
x = 1,
y = 2,
z = 3
};
this, to me, feels more consistent with de-structuring:
const {x,y,z} = someCoordinate;
where it'd feel clunky to do something like (I wouldn't do this)
const x = someCoordiante.x;
const y = someCoordiante.y;
const z = someCoordiante.z;
For related things (construction)
If multiple variables are created with the same constructor I'll often group them together also; I personally find this more readable
Instead of something like (I don't normally do this)
const stooge1 = Person("moe");
const stooge2 = Person("curly");
const stooge3 = Person("larry");
I'll usually do this:
const [stooge1, stooge2, stooge3] = ["moe", "curly", "larry"].map(Person);
I say usually because if the input params are sufficiently long that this becomes unreadable I'll split them out.
I agree with other folk's comments about use-strict

The concept of "cohesion over coupling" can be applied more generally than just objects/modules/functions. It can also serve in this situation:
The second example the OP suggested has coupled all the variables into the same statement, which makes it impossible to take one of the lines and move it somewhere else without breaking stuff (high coupling). The first example he gave makes the variable assignments independent of each other (low coupling).
From Coupling:
Low coupling is often a sign of a well-structured computer system and a good design, and when combined with high cohesion, supports the general goals of high readability and maintainability.
So choose the first one.

I believe that before we started using ES6, an approach with a single var declaration was neither good nor bad (in case if you have linters and 'use strict'. It was really a taste preference. But now things changed for me. These are my thoughts in favour of multiline declaration:
Now we have two new kinds of variables, and var became obsolete. It is good practice to use const everywhere until you really need let. So quite often your code will contain variable declarations with assignment in the middle of the code, and because of block scoping you quite often will move variables between blocks in case of small changes. I think that it is more convenient to do that with multiline declarations.
ES6 syntax became more diverse, we got destructors, template strings, arrow functions and optional assignments. When you heavily use all those features with single variable declarations, it hurts readability.

I think the first way (multiple variables) is best, as you can otherwise end up with this (from an application that uses KnockoutJS), which is difficult to read in my opinion:
var categories = ko.observableArray(),
keywordFilter = ko.observableArray(),
omniFilter = ko.observable('').extend({ throttle: 300 }),
filteredCategories = ko.computed(function () {
var underlyingArray = categories();
return ko.utils.arrayFilter(underlyingArray, function (n) {
return n.FilteredSportCount() > 0;
});
}),
favoriteSports = ko.computed(function () {
var sports = ko.observableArray();
ko.utils.arrayForEach(categories(), function (c) {
ko.utils.arrayForEach(c.Sports(), function (a) {
if (a.IsFavorite()) {
sports.push(a);
}
});
});
return sports;
}),
toggleFavorite = function (sport, userId) {
var isFavorite = sport.IsFavorite();
var url = setfavouritesurl;
var data = {
userId: userId,
sportId: sport.Id(),
isFavourite: !isFavorite
};
var callback = function () {
sport.IsFavorite(!isFavorite);
};
jQuery.support.cors = true;
jQuery.ajax({
url: url,
type: "GET",
data: data,
success: callback
});
},
hasfavoriteSports = ko.computed(function () {
var result = false;
ko.utils.arrayForEach(categories(), function (c) {
ko.utils.arrayForEach(c.Sports(), function (a) {
if (a.IsFavorite()) {
result = true;
}
});
});
return result;
});

A person with c background will definitely use the second method
var variable1 = "Hello, World!",
variable2 = "Testing...",
variable3 = 42;
the above method is more look like in c language

The main problem with the second one is that no IDE to date is respecting this style.
You cannot fold these structures.

We can use all the approaches, there is no need to go with one or the other. Applying different approaches can make the code easier to read.
I'll show real examples from one of my Vue.js 3 projects:
Example 1
const [store, route] = [useStore(), useRoute()]
const
showAlert = computed(() => store.getters['utils/show']),
userIsLogged = computed(() => store.getters['auth/userIsLogged']),
albumTitle = computed(() => store.getters['albums/title']);
Example 2
const
store = useStore(),
username = ref(''),
website = ref(''),
about = ref('');
const
isAppFirstRender = computed(() => store.getters['utils/isAppFirstRender']),
showToast = ref(false);
As you can see above, we can have small chunks of variable declarations. There is no need to declare big chunks. If I have let's say 12 variables I could group them in a way that makes sense or looks easier to read, without the verbosity:
const
numberOne = 5,
numberTwo = 10,
numberThree = 15;
const
stringOne = 'asd',
stringTwo = 'asd2',
stringThree = 'asd3';
let [one, two, three] = [1,2,3]
Ofcourse, everyone has their own style. This is my personal preference, using a mix of all approaches.
I personally don't like verbosity. I like code that has what it needs and not more.

Is a very nice feature. And no reason to avoid. As technology evolves, we must evolve our selves. This feature exists in some languages as Perl, for long time. For instance building a WebGL mesh, new javascript style
//initialize vertices with some calculated points
[verts[ix], verts[iy], verts[iz]] = ps[0];
[verts[ix + 3], verts[iy + 3], verts[iz + 3]] = ps[1];
[verts[ix + 6], verts[iy + 6], verts[iz + 6]] = ps[2];
//initializing normals with cross products
[norms[ix], norms[iy], norms[iz]] = cr;
[norms[ix + 3], norms[iy + 3], norms[iz + 3]] = cr;
[norms[ix + 6], norms[iy + 6], norms[iz + 6]] = cr;
And as a mater of fact, the old style code, it is much harder to debug, and by far much harder to understand and to find any bugs than above one. And this goes a lot, this sample is oversimplified. Lots of repetitive routines hindering the real logic, making code looking like some kind of magic. Same as above, but ancient style:
//initialize vertices with some calculated points
verts[ix] = ps[0][0];
verts[iy] = ps[0][1];
verts[iz] = ps[0][2];
verts[ix + 3] = ps[1][0];
verts[iy + 3] = ps[1][1];
verts[iz + 3] = ps[1][2];
verts[ix + 6] = ps[2][0];
verts[iy + 6] = ps[2][1];
verts[iz + 6] = ps[2][2];
//initializing normals with cross products
norms[ix] = cr[0];
norms[iy] = cr[1];
norms[iz] = cr[2];
norms[ix + 3] = cr[0];
norms[iy + 3] = cr[1];
norms[iz + 3] = cr[2];
norms[ix + 6] = cr[0];
norms[iy + 6] = cr[1];
norms[iz + 6] = cr[2];
Note, while migrating my code new style, I not only heavily deleted big blocks of routine code. I easily spotted inconsistencies that escaped lots of code reviews, just because of making the code much more easy to visualize, more laconic and logic oriented and much less routine oriented.

Related

Script to split JS comma-separated var declaration into multiple var declarations

I have a large codebase with a ton of stuff declared like this:
var x = 1,
y = {
//some object
},
z = function(arg) {
// some function
};
I'd like to run a node script to convert all this to
var x = 1;
var y = {
//some object
};
var z = function(arg) {
// some function
};
It's not as simple as running a regex on it, because as soon as an object or function appears, you can't just look for commas and semicolons anymore.
Is there an existing library or tool which can do this conversion for me? Not looking to minify or uglify the code, I'm just looking to modify existing, human-readable code to get rid of the comma-separated var declarations.
Are there situations where the character sequence , followed by an identifier and then a single = can exist outside of a multiple var declaration? I'm having trouble thinking of one outside of a string literal with those characters, because a single = is used for assignment, and I'm not sure why you'd have a comma before an assignment statement except in the initialization form you're trying to replace.
Granted, it's always risky to use regex in situations where a parser is more appropriate. The pattern would look something like:
,\s*([\$a-z_][\$a-z_0-9]*)(?=\s*=[^=])
Note: The Visual Studio plugin Resharper has a refactoring for this very operation. However, unlike many other refactorings, Resharper does not provide the option to apply this globally.
Maybe I'm missing something, but if all your comma separators lie at the end of a line, you could just use the regex:
replace(/,\n/g, ';\nvar ');
Here's a browser example:
// in node, this would come straight from a file
var string = 'var x = 1,\ny = {\n //some object \n},\nz = function(arg) {\n // some function\n};';
// heres an element we can use for results
var code = document.getElementById('code');
// lets show original string
code.innerHTML = string;
// lets show the new string in a couple of seconds
setTimeout( function () {
// the regex replace
var updated = string.replace(/,\n/g, ';\nvar ');
// updating the code element
code.innerHTML = updated;
// change color to signify finished
code.className = 'done';
}, 2000);
code {
white-space: pre-wrap;
white-space: -moz-pre-wrap;
white-space: -o-pre-wrap;
word-wrap: break-word;
}
.done {
background-color: #C0D9AF;
}
<code id="code"></code>
This seems to do the trick:
jsfmt --rewrite "a=b,c=d -> var a=b; var c=d;" input.js > output.js
input.js:
var x = 1,
y = {
//some object
},
z = function(arg) {
// some function
};
output.js:
var x = 1;
var y = {
//some object
};
var z = function(arg) {
// some function
};
using jsfmt

Javascript 'var variable' inside loop vs outside. Any difference in performence

for(var i=0;i<lines.length;i++) {
var line = lines[i];
vs
var line;
for(var i=0;i<lines.length;i++) {
line = lines[i];
Do this two snippets have different performance. If yes, please explain why.
I have run a benchmark on this and have found that there is pretty much no difference in performance.
If you would like to recreate it:
var lines = new Array(#BIG_NUMBER#);
lines.fill(#BIG_OBJECT#);
var a = (new Date()).getTime();
for(var i=0;i<lines.length;i++) {
var line = lines[i]; }
var b = (new Date()).getTime();
var line;
for(var i=0;i<lines.length;i++) {
line = lines[i]; }
var c = (new Date()).getTime();
console.log("a:" + (b-a) + " b:" + (c-b));
This makes sense, as there is almost no difference, both cases will create a local object that will be stored, and will be reassigning it multiple times.
Your code will work differently in both the cases.
In the first one line is a global variable an will be accessible outside the for loop, which is not the case in second one.
So I don't think performance comparison makes any sense here!
Even then, declaring a variable again and again is unnecessary though I don't think it is a complex operation. But yes declaring it repetitively will deteriorate the performance.

Eval vs IF statements (many IF statements)

This fiddle pretty much explains what I'm looking for. I'm trying to find the simplest way to go about coding something WITHOUT using eval. I can do it without eval but I think I will have to write 1000s of IF statements. Or is there another way?
http://jsfiddle.net/243rz8eq/9/
HTML
Eval way...<br>
Window-A<br>
Window-B<br>
Window-C<br><br>
Non-Eval way. Requires if statement for each window (there will be thousands). Or is there a simpler way I'm not seeing?<br>
Window-A<br>
Window-B<br>
Window-C<br><br>
JavaScript
window.core = {
launch: function(obj_string) {
//we init a blank dhtmlxwindow and do some other things here, then...
var x = eval("new " + obj_string); //fill dhtmlxwindow with proper content
},
launch_no_eval: function(id) {
//we init a blank dhtmlxwindow and do some other things here, then...
if (id==="window_a") var x = wins.a({x:1}); //fill dhtmlxwindow with proper content
else if (id==="window_b") var x = wins.b({x:1}); //fill dhtmlxwindow with proper content
else if (id==="window_c") var x = wins.c({x:1}); //fill dhtmlxwindow with proper content
//and so on for literally thousands of items.
}
};
window.wins = {
a: function(args) {
//this.myName = 'wins.a'; is used for the help topic.
//DB contains columns: [item] / [helpurl]
//Example Data: [wins.a] / [/help/gettingstarted.html]
//That is why in this previous post (http://stackoverflow.com/q/28096922/3112803)
//I was wanting to know if a function could know it's own name so I wouldn't
//have to type this line below for 1000s of items.
this.myName = 'wins.a';
console.log('Window-A is now displayed. Use "'+this.myName+'" to make link to help topic.');
},
b: function(args) {
this.myName = 'wins.b';
console.log('Window-B is now displayed. Use "'+this.myName+'" to make link to help topic.');
},
c: function(args) {
this.myName = 'wins.c';
console.log('Window-C is now displayed. Use "'+this.myName+'" to make link to help topic.');
}
};
Another approach would be to re-write the current usage of accessing object properties via the dot notation and use the bracket notation instead.
launch_no_eval:function(id) {
//we init a blank dhtmlxwindow and do some other things here, then...
if (id==="window_a") var x = wins.a({x:1}); //fill dhtmlxwindow with proper content
else if (id==="window_b") var x = wins.b({x:1}); //fill dhtmlxwindow with proper content
else if (id==="window_c") var x = wins.c({x:1}); //fill dhtmlxwindow with proper content
//and so on for literally thousands of items.
}
could be re-written as follows,
launch_no_eval:function(id) {
var x = wins[id]({x:1});
}
This would mean your HTML markup can change from,
Window-A<br>
Window-B<br>
Window-C<br><br>
to,
Window-A<br>
Window-B<br>
Window-C<br><br>
As Daniel commented below, assuming you have no control over the HTML markup and must use the window_# value being passed in then you could perform the following,
launch_no_eval:function(id) {
// replace 'window_' with empty string to retrieve unique id
var x = wins[id.replace('window_', '')]({x:1});
}

Last evaluated expression in Javascript

Is it possible in Javascript to get the result of the last evaluated expression? For example:
var a = 3;
var b = 5;
a * b;
console.log(lastEvaluatedExpression); // should print 15
So it would be something like eval() where it returns the last evaluated expression, but I cannot use eval().
There is no standard, reified concept of "the result of the last evaluated expression" in JavaScript. There are actually not too many languages that do have such a thing. Various JavaScript REPLs may provide some facility along these lines, but that's specific to those REPLs. Therei s no general "JavaScript" way.
-- package.json --
"dependencies": {
"stream-buffers": "^3.0.1"
},
-- main.js --
const streamBuffers = require('stream-buffers');
const repl = require('repl');
const reader = new streamBuffers.ReadableStreamBuffer();
const writer = new streamBuffers.WritableStreamBuffer();
const r = repl.start({
input: reader,
output: writer,
writer: function (output) {
console.log(output)
return output;
}
});
reader.push(`
var a = 3;
var b = 5;
a * b;`);
reader.stop();
-- output --
undefined
undefined
15
see: https://nodejs.org/api/repl.html
This is not possible in javascript. The only way I can think of right now (that doesn't involve writing a new interpreter) is to use Coffeescript. Coffeescript automatically returns the last expression.
http://coffeescript.org/
http://coffeescript.org/extras/coffee-script.js
That includes functions such as Coffeescript.compile and Coffeescript.eval.
There is no standard call for the last evaluated expression. No you would need to store values. For example you could do it like this:
var a = 3;
var b = 5;
var c = a * b;
var consoleResult = c.toString();
console.log(consoleResult); // should print 15
//Then make your program logic change the value of consoleResult, as needed.

JavaScript converting an array to array of functions

Hello I'm working on a problem that requires me to change an set array of numbers into an array that returns the original numbers as a function. So we get a return of a2 instead of a[2].
I dont want the answer I just need a hint. I know i can loop through the array and use .pop() to get the last value of the array, but then I dont know how to convert it to a function from there. any hints?
var numToFun = [1, 2, 3];
var numToFunLength = numToFun.length;
for (var i = 0; i < numToFunLength; i++) {
(function(num){
numToFun.unshift(function() {
return num;
});
}(numToFun.pop()))
}
DEMO
basically it pops out a number from the last, builds a function with that number returned, and put back into the first of the array. after one full cycle, all of them are functions.
here's the catch: how this works, it's up to you to research
why the loop does not look like the straightforward pop-unshift:
for (var i = 0; i < numToFunLength; i++) {
numToFun.unshift(function() { //put into first a function
return numToFun.pop() //that returns a number
});
}
and why i did this: (HINT: performance)
var numToFunLength = numToFun.length;
There's three important steps here:
Extract the number value from the array. Within a loop with an iterator of i, it might look like this:
var num = numArray[i];
This is important, because i will not retain its value that it had when you created the new function - it'll end up with the last value it had, once the for loop is finished. The function itself might look like this:
function() { return num; }
There's no reference to i any more, which is important - to understand better, read about closures. The final step would be to add the new function to the array of functions that you want.
...and you're done!
EDIT: See other's answers for good explanations of how to do this right, I will fix mine also though
As others have pointed out, one of the tricky things in javascript that many struggle with (myself included, obviously) is that scoping variables in javascript is dissimilar to many other languages; scopes are almost purely defined by functions, not the {} blocks of, for example, a for loop, as java/C would be.
So, below you can see (and in other answers here) a scoping function can aid with such a problem.
var numArray = [12, 33, 55];
var funcArray = [];
var numArrLength = numArray.length; // Don't do this in for loop to avoid the check multiple times
for(var j=0; j < numArrLength; j++) {
var scopeMe = function() {
var numToReturn = numArray[j];
console.log('now loading... ' + numToReturn);
var newFunc = function() {
return numToReturn;
};
return newFunc;
}();
funcArray.push(scopeMe);
};
console.log('now me');
console.log(funcArray);
console.log(funcArray[0]());
console.log(funcArray[1]());
console.log(funcArray[2]());
console.log(funcArray[1]()); // To ensure it's repeatable
EDIT my old bad answer below
What you'll want to do is something like
var funcArray = [];
for(...) {
var newFunc = function() {
return numArray.pop();
}
funcArray.push(newFunc);
}
The key here is that functions in javascript can be named variables, and passed around as such :)

Categories

Resources