Should I use a var per each require? [duplicate] - javascript

Reading Crockfords The Elements of JavaScript Style I notice he prefers defining variables like this:
var first='foo', second='bar', third='...';
What, if any benefit does that method provide over this:
var first='foo';
var second='bar';
var third='...';
Obviously the latter requires more typing but aside from aesthetics I'm wondering if there is a performance benefit gained by defining with the former style.

Aside of aesthetics, and download footprint, another reason could be that the var statement is subject to hoisting. This means that regardless of where a variable is placed within a function, it is moved to the top of the scope in which it is defined.
E.g:
var outside_scope = "outside scope";
function f1() {
alert(outside_scope) ;
var outside_scope = "inside scope";
}
f1();
Gets interpreted into:
var outside_scope = "outside scope";
function f1() {
var outside_scope; // is undefined
alert(outside_scope) ;
outside_scope = "inside scope";
}
f1();
Because of that, and the function-scope only that JavaScript has, is why Crockford recommends to declare all the variables at the top of the function in a single var statement, to resemble what will really happen when the code is actually executed.

Since JavaScript is generally downloaded to the client browser, brevity is actually quite a valuable attribute. The more bytes you have to download, the slower it gets. So yes, there is a reason apart from aesthetics, if not a massive one.
Similarly, you'll see people preferring shorter variable names to longer.
Personally, I don't bother minimising whitespace, as there are minimisers that can do this sort of thing for you (for example in YUI), and lack of indentation and spacing leads to less maintainable code.

No difference in semantics and no measurable difference in performance. Write whichever is clearest.
For simple examples like:
var first= 'foo', second= 'bar', third= 'bof';
the concise single-statement construct is probably a win for readability. On the other hand you can take this much too far and start writing half your program inside a single var statement. Here's a random example plucked from the jQuery source:
var name = match[1],
result = Expr.attrHandle[ name ] ?
Expr.attrHandle[ name ]( elem ) :
elem[ name ] != null ?
elem[ name ] :
elem.getAttribute( name ),
value = result + "",
type = match[2],
check = match[4];
I find this (by no means the worst example) a bit distasteful. Longer examples can get quite hard to read upwards (wait, I was in a var statement?) and you can end up counting the brackets to try to work out what's a multi-line expression and what's just an extended var block.

I believe that what he is going for is declaring all variables as abosultely the first statement in a function (You'll notice that JSLint complains about this if you use it and don't declare them on the first line). This is because of JavaScript's scope declaration limitations (or quirks). Crockford emphasizes this as good practice for maintainable JavaScript code. The second example declares them at the top, but not in the first execution statement. Personally, I see no reason as why to prefer the first over the second, but following the first does enforce that all variables are declared before doing anything else in the function.
David is right that the larger the script the more time it will take to down load, but in this case the difference between the two is minimal and can be handled by using YUI compress etc.

It's a personal programming style choice.
On the one hand there is readability, wherein placing each variable declaration on a separate line makes it more obvious what's going on.
On the other hand, there is brevity, wherein you're eliminating transmitting a few extra bytes over the network. It's generally not enough to worry about, unless you're dealing with slow networks or limited memory on the client browser side.
Brevity is also known as laziness on the part of the programmer, which is one reason that many purists avoid it.

It all comes down to personal taste or a set of style-guides, your development team follows. If you are serving JavaScript yourself, you usually compress or minify your script(s) into one long string in one single file. So the whole you-are-saving-bytes-and-your-scripts-download-faster argument is, well, not an argument :)
I usually declare my variables like this: (a style you didn't mention)
var something,
somethingElse,
evenMoreSomething,
andAnotherThing;

A statement like "var" is not minified/compressed.Every time you place a var, instead of a comma you lose 4 chars, if I count right.

Related

Why was the name 'let' chosen for block-scoped variable declarations in JavaScript?

I understand why var takes that name - it is variable, const - it is a constant, but what is the meaning behind the name for let, which scopes to the current block? Let it be?
Let is a mathematical statement that was adopted by early programming languages like Scheme and Basic. Variables are considered low level entities not suitable for higher levels of abstraction, thus the desire of many language designers to introduce similar but more powerful concepts like in Clojure, F#, Scala, where let might mean a value, or a variable that can be assigned, but not changed, which in turn lets the compiler catch more programming errors and optimize code better.
JavaScript has had var from the beginning, so they just needed another keyword, and just borrowed from dozens of other languages that use let already as a traditional keyword as close to var as possible, although in JavaScript let creates block scope local variable instead.
I guess it follows mathematical tradition. In mathematics, it is often said "let x be arbitrary real number" or like that.
Adding to exebook's response, the mathematics usage of the keyword let also encapsulates well the scoping implications of let when used in Javascript/ES6. Specifically, just as the following ES6 code is not aware of the assignment in braces of toPrint when it prints out the value of 'Hello World',
let toPrint = 'Hello World.';
{
let toPrint = 'Goodbye World.';
}
console.log(toPrint); // Prints 'Hello World'
let as used in formalized mathematics (especially the writing of proofs) indicates that the current instance of a variable exists only for the scope of that logical idea. In the following example, x immediately gains a new identity upon entering the new idea (usually these are concepts necessary to prove the main idea) and reverts immediately to the old x upon the conclusion of the sub-proof. Of course, just as in coding, this is considered somewhat confusing and so is usually avoided by choosing a different name for the other variable.
Let x be so and so...
  Proof stuff
 New Idea { Let x be something else ... prove something } Conclude New Idea
 Prove main idea with old x
It does exactly what the var does with a scope difference. Now it can not take the name var since that is already taken.
So it looks that it has taken the next best name which has a semantic in an interesting English language construct.
let myPet = 'dog';
In English it says "Let my pet be a dog"
The most likely possibility is that it was the most idiomatic choice. Not only is it easy to speak, but rather intuitive to understand. Some could argue, even more so than var.
But I reckon there's a little more history to this.
From Wikipedia:
Dana Scott's LCF language was a stage in the evolution of lambda calculus into modern functional languages. This language introduced the let expression, which has appeared in most functional languages since that time.
State-full imperative languages such as ALGOL and Pascal essentially implement a let expression, to implement restricted scope of functions, in block structures.
I would like to believe this was an inspiration too, for the let in Javascript.
It could also mean something like "Lexical Environment Type or Tied".. It bothers me that it would simply be "let this be that". And let rec wouldn't make sense in lambda calculus.
Let uses a more immediate block level limited scope whereas var is function scope or global scope typically.
It seems let was chosen most likely because it is found in so many other languages to define variables, such as BASIC, and many others.
I think JavaScript's indebtedness to Scheme is obvious here. Scheme not only has let, but has let*, let*-values, let-syntax, and let-values. (See, The Scheme Programming Language, 4th Ed.).
((The choice adds further credence to the notion that JavaScript is Lispy, but--before we get carried away--not homoiconic.))))

limiting side effects when programming javascript in the browser

Limiting side effects when programming in the browser with javascript is quite tricky.
I can do things like not accessing member variables like in this silly example:
let number = 0;
const inc = (n) => {
number = number + n;
return number;
};
console.log(inc(1)); //=> 1
console.log(inc(1)); //=> 2
But what other things can I do to reduce side effects in my javascript?
Of course you can avoid side effects by careful programming. I assume your question is about how to prevent them. Your ability to do so is severely limited by the nature of the language. Here are some approaches:
Use web workers. See MDN. Web workers run in another global context that is different from the current window.:
Isolate certain kinds of logic inside iframes. Use cross-window messaging to communicate with the iframe.
Immutability libraries. See https://github.com/facebook/immutable-js. Also http://bahmutov.calepin.co/avoid-side-effects-with-immutable-data-structures.html.
Lock down your objects with Object.freeze, Object.seal, or Object.preventExtensions. In the same vein, create read-only properties on objects using Object.defineProperty with getters but no setters, or with the writeable property set to false.
Use Object.observe to get asynchronous reports on various types of changes to objects and their properties, upon which you could throw an error or take other action.
If available, use Proxy for complete control over access to an object.
For considerations on preventing access to window, see javascript sandbox a module to prevent reference to Window. Also http://dean.edwards.name/weblog/2006/11/sandbox/. Finally, Semi-sandboxing Javascript eval.
It is useful to distinguish between inward side effects and outward side effects. Inward side effects are where some other code intrudes on the state of my component. Outward side effects are where my code intrudes on the state of some other component. Inward side effects can be prevented via the IIFEs mentioned in other answers, or by ES6 modules. But the more serious concern is outward side effects, which are going to require one of the approaches mentioned above.
Just what jumps to my mind thinking about your question:
Don't pollute the global namespace. Use 'var' or 'let', those keywords limit your variables to the local scope.
"By reducing your global footprint to a single name, you significantly reduce the chance of bad interactions with other applications, widgets, or libraries." - Douglas Crockford
Use semicolons
The comment section of this article provides some good (real life) reasons to always use semicolons.
Don't declare String, Number or Boolean Objects(in case you were ever tempted to)
var m = new Number(2);
var n = 2;
m === n; // will be false because n is a Number and m is an object
"use strict"; is your friend. Enabling strict mode is a good idea, but please don't add it to existing code since it might break something and you can not really declare strict only on lexical scopes or individual scripts as stated here
Declare variables first. One common side effect is that people are not aware about JavaScript's Hoisting. Hoisting searches your block for variable declaration and moves them all together to the top of your block.
function(){
var x = 3;
// visible variables at runtime at this point: x,y,i !
// some code....
var y = 1; // y will be moved to top!
for( var i = 0; i < 10; i++ ){ // i will be moved to top!
// some code...
}
}
Here is discussed what hoisting actually means and to what kind of 'unexpected behaviour' it may lead.
use '===' instead of '=='. There are many good reasons for this and this is one of the most common 'side effects' or 'errors' in JavaScript.
For more details see this great answer on SO, but let me give you a quick demonstration:
'' == '0' // false
0 == '' // true
// can be avoided by using '==='
'' === '0' // false
0 === '' // false
Make use of IIFE. An IIFE (Immediately Invoked Function Expression) lets you declare an anonymus function which will call itself. This way you can create a new lexical scope and don't have to worry about the global namespace.
Be careful with prototypes. Keep in mind that JavaScript objects of the same class share the same prototype. Changing a prototype means changing the behaviour of all instances of the class. (Even those which are used by other scripts/frameworks) like it happened here
Object.prototype.foo = function(){...} // careful!
Those are the 'side effects' that came to my mind. Of course there is way more to take care of (meaningful variable names, consistent code style etc...) but I don't consider those things as 'side effects' since they make your code hard to maintain, but won't break it immediately.
My favorite trick is to just use a language that compiles to javascript, instead of using javascript.
However, two important tricks you can do :
start your file with "use strict";. This will turn on validation of your code and prevent usage of undeclared variables. Yes, that's a special string that the browser will know how to deal with.
use functions when needed. Javascript cannot do normal scopes, but for functions it works fine, so get (function() { })(); in your muscle memory.
Normal CS fundamentals also apply: separate your code into logical pieces, name your variables properly, always explicitly initialize variables when you need them, etc.

All possible ways to declare Javascript variables

To create an IDE that would autocomplete all variables the user declares but would be oblivious to other variables such as Math.PI or even the module Math, the IDE would need to be able to identify all identifiers relating to variables declared by the user. What mechanism could be used to capture all such variables, assuming you already have access to the AST (Abstract Symbol Table) for the program?
I am using reflect.js (https://github.com/zaach/reflect.js) to generate the AST.
I think it's pretty much impossible
Here is why I think it's pretty much impossible without executing it:
Let us go through the unexplored parts, from easy to hard.
Easy to catch:
Function scope is missed here:
(function(x){
//x is now an object with an a property equal to 3
// for the scope of that IIFE.
x;
})({a:3});
Here is some fun dirty tricks for you all.:
Introducing... drum roll... Block Scoping!!
with({x:3}){
x;//x is now declared in the scope of that with and is equal to 3.
}
try{ throw 5}catch(x){
x // x is now declared in the scope of the try block and is equal to 5;
}
(people reading: I beg you to please not use these last two for actual scoping in code :))
Not easy:
Bracket notation:
var n = "lo";
a["h"+"e"+"l"+n] = "world"; // need to understand that a.hello is a property.
// not a part of the ast!
The really hard parts:
Let us not forget invoking the compiler These would not show up in the AST:
eval("var x=5"); // declares x as 5, just a string literal and a function call
new Function("window.x = 5")();// or global in node
In node.js this can also be done with the vm module. In the browser using document.write or script tag injection.
What else? Of course they can obfuscate all they want:
new Function(["w","i","n","dow.x"," = ","5"].join(""))(); // Good luck finding this!
new Function('new Function(["w","i","n","dow.x"," = ","5"].join(""))()')();// Getting dizzy already?
So what can be done?
Execute the code, once, in a closed, timed environment when you update the symbol table (just the relevant parts)
See what's the generated symbol table is from the execution
Boom, you got yourself a symbol table.
This is not reliable but it's probably as close as you get.
The only other alternative I can think of, which is what most IDEs are doing is to simply ignore anything that is not:
object.property = ... //property definition
var a = ... //scoped
b = ... //global, or error in strict mode
function fn(){ //function declaration
object["property"] //property with a _fixed_ literal in bracket notation.
And also, function parameters.
I have seen no IDE that has been able to deal with anything but these. Since they're the most common by far, I think it's perfectly reasonable to count those.
By adding them onto am object that already exists....ie
window.mynewvar = 5;
function mynewfunc() {
}

replace js function keyword with f

I want to know if it's possible to do something like:
var f = function;
and than use f like it would be the js function keyword
if something like this would be possible I would use it for js code minimization, cuz I have a lot of function in my code
Similar to what Pointy pointed out in the comments, what you can do is use the function constructor to create a new function and pass it as string. In other words:
function f(s) { return new Function(s) };
var foo = f('var s = "hello"; return s');
alert(foo()); //=> "hello"
But again, I think this is unnecessary.
Edit: To add parameters you'd use the arguments object.
function f() {
var args = Array.prototype.slice.call(arguments);
var func = args.pop();
return new Function(args.join(','), func);
}
var add = f('a,b', 'return a + b');
It is not possible to do as you describe.
The closest I can think of is to make a function for generating functions, using eval to parse a passed string. Using eval however, is generally evil and should be avoided. Overall, I would not recommend doing something like this at all.
Also, it is worth noting that there is very little point in doing what you want, as javascript sent over the wire should be compressed first, so the the word function will be represented by one token, regardless of how long the word is.
If you want your source code to be more readable and concise, I would recommend coffee-script which compiles to javascript, and allows you to define functions without using even the first letter of function. Chuck Norris would approve!
Summary of conclusions and recommendations
use coffee-script for cruft free source
compile it to verbose javascript you never look at
minify that javascript (uglify is a great compressor, or google's closure)
gzip it (will compress repetitive strings well)
send it
The key issue here is that after it is gzipped, the size of the word function becomes irrelevant, so the only remaining issue is the readability of your source code.
Yeah...to be quite honest, I wouldn't worry about trying to shorten the function keyword to 'f' which gives you back very little for the work and it would also hurt the readability of your code. And, unless you have something like a million functions, I wouldn't focus on that. As #prodigitalson said - run it through a minifier. That should take care of the real minifications that are possible in your code and still maintain readability in your code base (which is more important than saving a few bytes).
Also, per my comment, there is something (potentially) on its way to replace the long 'function' keyword (something Brendan Eich has said he would have considered changing - you have to remember that he designed the language in 10 days or so). Read more about it here: Fat Arrow Syntax Of course, these sorts of things can always change...but the standards definition bodies are looking at it.
You could do this with the hygenic macro functionality of http://sweetjs.org/

Scope on Object not Behaving as Expected

I'm trying to clean up a long-standing bad habit in coding: Writing widgets to the global scope.
I've made a large, mostly self-contained script for a news roll on a webpage and was pleasantly surprised at how well it worked after I stuffed the whole thing into a function... TOO well in fact.
To ensure I wasn't cheating, I wrote the following code to make sure my scoping was correct:
var story_count = "THIS IS NOT A NUMBER";
console.log(story_count);
touch_roll = function()
{
this.story_count = 0;
}
console.log(story_count);
touch_roll();
console.log(story_count);
Fully expecting this to yield the following response in the console
THIS IS NOT A NUMBER
THIS IS NOT A NUMBER
THIS IS NOT A NUMBER
I was entirely surprised to find the output was, in fact, this:
THIS IS NOT A NUMBER
THIS IS NOT A NUMBER
0
Is this not what I think it is? Research hasn't really helped, but I'm a little burnt out so it's entirely possible I'm reading it all wrong. If not this, then how DO I keep all of my namespaces completely within the scope of that function so as not to mess with existing bits on the site?
As per Matt's answer below, here is the corrected code:
var story_count = "THIS IS NOT A NUMBER";
console.log(story_count);
var touch_roll = new function()
{
this.story_count = 0;
console.log(story_count);
}
console.log(story_count);
By declaring touch_roll as a var and instantiating the function as new Javascript evaluates said function into an object as run-time (so we can also remove the call to touch_roll() at the bottom).
The corrected output is as follows:
THIS IS NOT A NUMBER
0
THIS IS NOT A NUMBER
Because you're not invoking touch_roll with new, this is the window object (which is what global variables in browser environments belong to).
If you were to use new, then you'd get:
THIS IS NOT A NUMBER
THIS IS NOT A NUMBER
THIS IS NOT A NUMBER
Additionally, you're declaring touch_roll as a implicit global variable. Either use function declaration syntax, or add a var to it.

Categories

Resources