what do curly braces mean in react library code? [duplicate] - javascript

Just opened a client's javascript file and the first lines are along the lines of this:
{
var s_account="blog";
}
Which I don't get. Normally, in my experience, curly braces wrap around a function...
function welcome(){ ...
...or a json JavaScript object
var attributes = { this : "that...
Can anyone tell me why there are curly braces with no text before them or after them? What does it do / what is the point of it?

It's a block and completely pointless unless you label it:
block: {
var s_account="blog";
console.log("executed");
break block;
console.log("not executed");
}

The only logical reason to do something like this, in my mind, is as an organizational technique.
function banana(){
// private members
{
var foo = "foo",
bar = "bar",
baz = "baz";
function bux(){
console.log("bux");
}
}
// public members
this.fin = "fin";
this.fang = "fang";
this.foom = "foom";
this.shamalamadingdong = function(){
bux();
};
}
Also, most IDEs will allow you to collapse that "private members" block and get it out of your way.

That's a block statement. Block statements have multiple purposes, none of which are being used by that code (other than perhaps to group the content together as Shmiddty suggested). (In fact, I'd say in that code they're counter-productive, because for the many people coming to JavaScript from languages where all variable declarations are block-scoped, they create the impression that the variable is scoped to the block, which it isn't.)
Uses it can have:
Scoping let, const, and class
If that code were using let, const, or class, the block would scope the resulting identifier because let, const, and class are block-scoped in JavaScript. So this outputs "bar":
{
var foo = "bar";
}
console.log(foo);
but this throws a ReferenceError because foo is scoped to the block:
{
let foo = "bar";
}
console.log(foo);
Providing a block to break
As Esailija points out, if it were labelled and using break, the break would exit the block early.
Grouping statements attached to a flow-control statement
The most common use of a block statement is to group together the statements attached to a flow-control statement like if and for. In this fairly typical if:
if (something) {
doThis();
doThat();
}
...the {} aren't part of the if (you can write if without using {}), they're a block statement attached to the if.

Can anyone tell me why there are curly braces with no text before them or after them? What does it do / what is the point of it?
There is no significant point to them in Javascript. It will act exactly the same as if the code was just
var s_account="blog";
Speculation
In other languages which have block scope, this might restrict the scope of the variable, but since JS doesn't have that feature (for better or worse), braces without a control structure or function are essentially meaningless and ignored.
Most likely this code was left over from a deleted function or if statement however. It definitely is not a pattern to be copied.

It's called a block statement. It lets you group expressions. It's normally used with control structures like if and while, but can also be used on its own.
Since JavaScript doesn't have block scope, the code runs in the same scope (as if the {} weren't there).
Example:
{
var s_account="blog";
}
console.log(s_account);
That works fine.

Quick addition.
In some IDE like Visual Code, putting Curly Braces will actually create a visual block with a 'drop-down' arrow, allowing you to completely hide a portion of code with just a click.
It helps with code organization.
I'm using it when creating HTML element with a lot of CSS.
Since it does not affect code execution, this is very useful.

Related

Why is var not deprecated?

Lately after ES6 released, many sources suggested that I use "const" and "let" instead of "var", and that I should stop using "var" in my JavaScript.
What I wonder is, if "var" has no advantage over "let" in all points of view, then why didn't they just fix var, or even deprecate "var" instead of letting them go along side each other?
Backwards compatibility.
You're right in saying there is no real advantage to using var over let - if you define them at the start of a function their meaning is basically identical.
You're right that there is no real reason to write new code using var (except maybe this, if relevant).
There are pages on the internet that are decades old though, and no one is going to rewrite them. There is nothing really to gain by removing var from the language. For languages like HTML and Javascript that are interpreted - backward compatability is absolutely mandatory.
That is also why they chose not to simply redefine var. Take the following example code;
// THIS IS AN EXAMPLE OF BAD CODE. DO NOT COPY AND PASTE THIS.
if (logic) {
var output = "true"
} else {
var output = "false"
}
console.log(output)
If var was changed to behave like let then the console.log would cause a reference error because of the scope difference.
I believe sometimes you need to redeclare a variable to write less code.
One example is this function that generates a unique id:
function makeUniqueId(takenIds) {
do {
var id = Number.parseInt(Math.random() * 10);
} while (takenIds.includes(id))
}
Which may be invoked like that
makeUniqueId([1,2,3,4,5,6,7])
Here I declare id variable simply inside do block and it get's "hoisted" to the function scope. That would cause an error if I used let, because while block wouldn't see the variable from the do block. Of course I could declate let before do..while, but that would create the same function scoped variable with extra line of code.
Another example is when you copypaste code to devtools console and every time variables get redeclared.
One more example. What if you want to keep your variable declarations close to their usages but still treat them as function globals? If you use let in this fashion, you'll get rather confusing expirience in dev tools (all those Block, Block scopes).
But var 'keeps' them together in one 'Local' list:
Everything has their own advantages and disadvantages using var const and let is dependent on their use cases.
var
Variable declarations are processed before the execution of the code.
The scope of a JavaScript variable declared with var is its current execution context.
The scope of a JavaScript variable declared outside the function is global.
let
The let statement allows you to create a variable with the scope limited to the block on which it is used.
const
const statement values can be assigned once and they cannot be reassigned. The scope of const statement works similar to let statements.
I hope you understand.

Should we manually hoist all the JavaScript variables to the front of the function definition?

I have heard that since JavaScript would hoist all the local variables to the front of the function, it is better if the programmer just hoist it himself or herself, so that everything is seen as how things would actually occur.
Example is:
var i, result = [];
which is to declare all local variables at the beginning of the function.
But I also saw in some classical code, such as in React JS's source code that it would do
for (var i = 0; i < ...; i++) { ... }
that is, declaring it when i is first used -- so that if this line is removed, the declaration will be removed together.
If we hoist it manually, there is a danger that when that loop is removed, the var i; is still left there. (although linting probably would catch it).
I also have seen weird look from interviewers when I hoists all the variables to the front of the function definition too.
Should we hoist all variables to the front? Or what if we hoist all variables except the temporary variables such as i and j?
Limiting the exposure of variables to the context they are useful in can be an extremely valuable auto-documentation strategy: It lets the next person who picks up the code know where variables are and are not relevant. So no, don't "hoist" because the JavaScript engine is internally doing it
I also have seen weird look from interviewers when I hoists all the variables to the front of the function definition too.
Should we hoist all variables to the front? Or what if we hoist all variables except the temporary variables such as i and j?
There are basically two schools of thought on this. One is to declare all of your variables in one place, usually at the top of whatever they are scoped to (which is the function in which they are defined, if you are using the var keyword). The other school of thought is to declare variables as closely as you can to where they are used. They both have valid arguments, and honestly is a matter of opinion and preference.
Before getting into let and ES6, I will first talk about the two arguments above.
Declaring at the top of the scope
The advantages of this are that you always know where your variable declarations are, and you are always aware of the parent scope. Immediately when looking at the function, you can determine what variables are used throughout, and you can trace where they are used from there.
The disadvantages of this are that, depending on your code structure, it may be 100 lines from where a variable is declared and where it is used, which can make debugging a bit of a challenge sometimes and requires you to carefully trace the variable you think you are using in the function, because it may not always be the one declared at the top, especially in the case of shadowing.
Declaring as close in proximity to where the variables are used
The advantages of this are that when trying to determine variable scoping and shadowing, it is very easy to determine what version of the variable you are working with (especially with nested functions). The other advantage is code-cleanup. If you remove a function or a loop and there is a variable declaration right above it, it is usually a pretty good reminder to remove that variable declaration as well because it will not be needed anymore. Obviously that's not always the case, but many times it is. When declaring at the top, variables can get lost in a sea of declarations and be left unused - yeah a linter can catch that, so it may be a moot point, but it's a point nonetheless.
The disadvantages of this are the exact opposite of the advantages of declaring at the top. If you are looking to see what variable names / identifiers are used in a given scope, you kind of have to go digging. CTRL + F is your friend, but it is faster to look at a list that is all in one place.
Now what about let??
Again, there are two schools of thought on this: one is "let is the new var" and the other is that "let simply allows us to do syntactically what we already were doing stylistically"
For example, take this code:
var result;
for (var i = 1; i <= 10; i++) {
result = 2 * i;
console.log(result);
}
Vs.
for (var i = 1; i <= 10; i++) {
var result = 2 * i;
console.log(result);
}
Now, from the compiler's perspective, they are identical. However, the second version (stylistically) is telling the reader of the code "The result variable is only being used inside this for loop", whereas the first version is ambiguous to the reader as to what may or may not be happening to the result variable later on in the code. These are stylistic and conventions that developers unspokenly adhere to in order to convey intent of the code. And that is the argument of the second school of thought - let simply allows us to do, syntactically, what we are already doing stylistically.
This might have been relevant a few years back.
Now, you should use ES5 or later, which introduced the let keyword, which solves the hoisting issue. let declared variables are block-scoped and will not be hoisted.
I guess sometimes it makes sense to use strict mode
"use strict";
which can be implemented for the whole file or for a function
function strictFunction() {
"use strict";
var y = 3.14; // This is ok
x = 2.414; // This will cause error
}
which can help writing more secure code by avoiding global variables. So technically it depends how your for loop is being use. Reference "use strict";
You can also use let instead or var as suggested by #RemcoGerlich to scope your variables

Can I use curly braces in javascript to separate sections of code

Here is some sample code. I'd like to know if there is any reason why I shouldn't do this.
//some code
var x = "hello";
{
var y = "nice";
function myfunction() {
//do stuff . . .
}
}
The benefit of doing this I see is being able to organize sections of code in chunks and have auto formatters do some work with that...
In my tests {} does not affect the scope when creating a var or function.
This answer was written in times of earlier JavaScript implementations. While the same rules for var apply, ECMAScript 2015 (aka ES6) introduce the let variable declaration statement, which follows "traditional" block-scoped rules.
Example of let scoping with a Block, which logs "1", "2", "1":
{ let x = 1; console.log(x); { let x = 2; console.log(x) }; console.log(x) }
The MDN Reference on Block summarizes the usage of blocks as:
Important: JavaScript does not have block scope. Variables introduced with a block are scoped to the containing function or script, and the effects of setting them persist beyond the block itself. In other words, block statements do not introduce a scope. Although "standalone" blocks are valid syntax, you do not want to use standalone blocks in JavaScript, because they don't do what you think they do, if you think they do anything like such blocks in C or Java.
As discussed on MDN, the syntax is perfectly valid as { StatementList } (aka Block) is a valid Statement production..
However; and because this is very important: a new block does not introduce a new scope. Only function bodies introduce new scopes. In this case, both the x and y variables have the same scope.
In addition a FunctionDeclaration should appear only as a top-level statement - that is, it must be a statement directly under a Program or Function body, not a Block. In this case the declaration of myfunction is "not reliably portable among implementations".
There is the IIFE (Immediately Invoked Function Expression) pattern which can be used and, while it addresses the technical issues above, I would not recommend it here as it complicates the code. Instead, I would simply create more named functions (named functions can be nested!), perhaps in different modules or objects, as appropriate.
var x = "hello";
;(function () {
// New function, new scope
// "y" is created in scope, "x" is accessible through the scope chain
var y = "nice";
// Now VALID because FunctionDeclaration is top-level of Function
function myfunction() {
}
})(); // Invoke immediately
// No "y" here - not in scope anymore
Realize this is old, but figured I would update for ES2015.
The do have a bit more meaning with let + const as found here https://babeljs.io/docs/learn-es2015/
function f() {
{
let x;
{
// okay, block scoped name
const x = "sneaky";
// error, const
x = "foo";
}
// okay, declared with `let`
x = "bar";
// error, already declared in block
let x = "inner";
}
}
I don't understand the reasoning behind the outermost curly braces, but functions are always written inside curly braces in javascript.
If you are working with other developers they may find the outer curly braces more confusing than helpful and there could be some negative effects : https://web.archive.org/web/20160131174505/http://encosia.com/in-javascript-curly-brace-placement-matters-an-example/
There are probably many reasons NOT to write code this way... readability is #1, as most would find this makes the code harder to read. However, there is technically nothing wrong with coding like this, and if it's easier for you to read, then it should be fine.
I think there will be problems with this convention when you start coding more complex programs. There must be a good reason why people don't code like that other than adding extra lines of code.
But since Javascript doesn't have block scoping, the code will still work.

Why single var is good in javascript?

Can anyone tell me why use one var declaration for multiple variables and declare each variable on a newline consider is a good programming behavior?
// bad
var items = getItems();
var goSportsTeam = true;
var dragonball = 'z';
// good
var items = getItems(),
goSportsTeam = true,
dragonball = 'z';
It is not considered 'good' or 'bad'. It's a matter of preference.
The guy who built the code quality tool JSLint, Douglas Crockford likes it.
One 'advantage' it might have is that it avoids the possibility of variable hoisting. In JavaScript all var declarations move to the top of their scope automatically.
Here is why Crockford thinks the second option is better:
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. This can be declined with the vars option.
It's a preference, I wouldn't say good or bad. Yes JSLint complains about it, I don't really like how it complains about for loop variables being inline as well. The reason that it was put in JSLint was to prevent possible hoisting confusions.
Also in some cases declaring all of your variables at the top will lead to a slightly smaller file. Consider the following:
var a = 10;
a++;
var b = 20;
After Google Closure being run over it
var a=10;a++;var b=20;
As opposed to this if we pull b's declaration to the top.
var a=10,b;a++;b=20;
The main benefit (aside from style preference, I guess) is that it will prevent you from writing code that suffers from unintended variable hoisting consequences.
Take this example:
var foo = function(){alert('foo');}
function bar(){
foo();
var foo = function(){alert('foobar')};
foo();
}
bar();
By reading this code, the intent of bar appears to be as follows:
Call the outer foo function to alert the string 'foo'.
Create a local variable, foo.
Call the local foo function to alert the string 'foobar'.
In reality, what happens is this:
The local variable foo is hoisted to the top of the bar function.
foo now actually refers to the local variable instead of the outer variable of the same name. But since the local hasn't been assigned yet, its value is undefined. Hence, when you try to invoke foo, you'll get a TypeError.
Nothing. Because you threw an error. That's it. Your code broke.
The arguments for Crockfords preference have been well made and are valid. I am just beginning to return to the first format now however, as I believe that for experienced developers who understand variable hoisting and are not likely to fall foul to it, there are 2 advantages that I can think of:
When new variables are added to the list of definitions, diffing is made easier. This means you are likely to experience fewer merge conflicts (simple though they may be to resolve) and less cognitive load when analysing diffs. For similar reasons I have also been converted to dangling commas, which I would never have expected xD
As #ldsenow identified, it can make searching for variable definitions more simple. You will always be able to search for var <name> and get the result you want and nothing else.

HTML5 drag & drop events in Javascript

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);

Categories

Resources