JavaScript is one of the most successful flames generator in history! Besides the flaws it has (which are, in part, addressed in the new ECMAScript specifications), most programmers hate JavaScript for 2 reasons:

The DOM, which they erroneously think is equivalent to the JavaScript language, which has quite a terrible API.

They come to JavaScript from languages like C and Java. They are fooled by JavaScript’s syntax into believing that it works the same way as those imperative languages do. This misconception will lead to confusion, frustration, and bugs.

That’s why, generally, JavaScript has a worse reputation than it deserves.

During my career, I noticed a few patterns: language features most developers with a Java or C/C++ background assume to be identical in JavaScript, while they are completely different.

This article gathers the most troublesome ones, comparing the Java-way to the JavaScript-way to shown differences and highlight best practices in JavaScript.

Scoping

Most developers start working on JavaScript because they are forced, and almost every of them start writing code before taking a moment to learn the language. Every such developer has been tricked by JavaScript scope at least once.

First, in JavaScript variable scope is determined by functions, not by brackets. In other words, if and for bodies don’t create a new scope, and a variable declared inside their bodies is actually hoisted, i.e. created at the beginning of the innermost function in which it is declared, or of the global scope otherwise.

Second, the presence of the with statement forces JavaScript scoping to be dynamic, impossible to determine until runtime. You might not be surprised to hear that the use of the with statement is deprecated: JavaScript stripped of with would actually be a lexically scoped language, i.e. the scope could be completely determined by looking at the code.

Formally, in JavaScript there are four ways for a name to enter a scope:

Language-defined: by default all scopes contains the names this and arguments.

Formal parameters: any (formal) parameters declared for a function is scoped to the body of that function.

Function declarations.

Variable declarations.

One further complication is caused by the implicit global scoping assigned to variables declared (implicitly) without the var keyword. This madness pairs with the implicit assignment of the global scope to this reference when functions are called without an explicit bind (more on this in next sections).

Before delving into the details, let’s clearly state the good pattern that can be used to avoid confusion:

Use strict mode ('use strict';), and move all variables and functions declaration at the top of each function; avoid variables declaration inside for and if blocks, as well as function declarations inside those blocks (for different reasons, that goes beyond the scope of this article).

Hoisting

Hoisting is a simplification that is used to explain the actual behavior of declarations. Hoisted variables are declared at the very beginning of the function containing them, and initialized to undefined. Then assignment takes place in the actual line where the original declaration was.

What values do you expect to be printed to the console? Would you be surprised to the following output?

undefined
0
5
5

Inside the if block, the var statement doesn’t declare a local copy of the variable i, but rather overwrites the one declared before. Notice that the first console.log statement prints the actual value of variable i, which is initialized to undefined. You can test it by using the "use strict"; directive as the first line in the function. In strict mode variables must be declared before being used, but you can check that JavaScript engine won’t complain for the declaration. On a side note, be aware that you will get no complain for redeclaring a var: if you want to catch such bugs, you should better process your code with a linter such JSHint or JSLint.

Let’s now see one more example to highlight another error-prone use of variable declarations:

Despite you might expect differently, the if body is executed because a local copy of a variable named notNull is declared inside the test() function, and it is hoisted. Type coercion also plays a role here.

Function Declarations vs Function Expressions

Hoisting doesn’t apply to variables only, function expressions, which are variables to all intents and purposes, and function declarations are hoisted as well. This topic needs to be treated with way more care than I’ll do here, but in short function declarations behaves mostly as function expressions, except that their declarations are moved to the beginning of their scope.

Consider the following example showing the behavior of a function declaration:

With

The following example shows a situation where scoping can only be determined at runtime:

function foo(y) {
var x = 123;
with(y) {
return x;
}
}

If y has a field named x, then function foo() will return y.x, otherwise it will return 123. This coding practice is a possible source of runtime errors, hence it’s highly recommended that you avoid using the with statement.

Looking at the Future: ECMAScript 6

ECMAScript 6 specifications will add a fifth way to add block-level scoping: the let statement. Consider the code below:

In the code above, the variables i and j will exist only inside the block. At the time of writing, the support for let is limited, even for Chrome.

Scope in a Nutshell

The next table summarizes the scope in different languages:

Feature

Java

Python

JavaScript

Warnings

Scope

Lexical (block)

Lexical (function, class or module)

Yes

It works very differently from Java or C

Block scope

Yes

No

`let` keyword (ES6)

Again, warning: this is not Java!

Hoisting

No way!

No

Yes

For variables and function expressions, only declaration is hoisted. For function declarations, the definition is hoisted as well

Functions

Another very misunderstood feature of JavaScript are functions, especially because in imperative programming languages like Java there is no such a concept as a function.

As a matter of facts, JavaScript is a functional programming language. Well, not a pure functional programming language as Haskell – after all it still has an imperative style, and mutability is encouraged rather than simply allowed, as for Scala. Nevertheless JavaScript could be used as a purely functional programming language, with function calls deprived of any side effect.

First-Class Citizens

Functions in JavaScript can be treated like any other type, for example String and Number: they can be stored in variables, passed as arguments to functions, returned by functions, and stored in arrays. Functions can also have properties and can be changed dynamically and that’s because…

Objects

One very surprising fact, for most JavaScript newbies, is that functions are actually objects. In JavaScript every function is actually a Function object. The Function constructor creates a new Function object:

var func = new Function(['a', 'b', 'c'], '');

This is (almost) equivalent to:

function func(a, b, c) { }

I said they are almost equivalent because using the Function constructor is less efficient, produces an anonymous function, and do not create a closure to its creation context. Function objects are always created in the global scope.

Function, the type of functions, is built upon Object. This can be easily seen by inspecting any function you declare:

This means that functions may and do have properties. Some of them are assigned to the functions on creation like name or length. These properties return the name and number of arguments in the function definition respectively.

Functions in a Nutshell

The following table describes functions in Java, Python, and JavaScript:

Feature

Java

Python

JavaScript

Warnings

Functions as built-in types

Lambdas, Java 8

Yes

Yes

Callbacks / Command Pattern

Objects (or lambdas for Java 8)

Yes

Yes

Functions (callbacks) have properties that can be modified by the “client”

Dynamic creation

No

No

`eval` – `Function` object

`eval` has security concerns and `Function` objects might work unexpectedly

Properties

No

No

Can have properties

Access to function’s properties can’t be restricted

Closures

If I had to choose my favorite JavaScript feature, I’d go for closures, no doubt. JavaScript was the first mainstream programming language to introduce closures. As you might know, Java and Python have had a weakened version of closures for a long time, where you could only read (some) values from enclosing scopes.

In Java, for instance, anonymous inner class provides closure-like functionality with some restrictions. For example, only final local variables can be used in their scope – better said, their values can be read.

JavaScript allows full access to the outer scope variables and functions. They can be read, written, and if needed even hidden by local definitions: you can see examples of all these situations in the “Scoping” section.

Even more interesting, a function created in a closure remembers the environment in which it was created. By combining closures and function nesting, you can have outer functions returning inner functions without executing them. Besides, you can have local variables of the outer function surviving in the closure of the inner one long after the execution of the function in which they are declared has ended. This is a very powerful feature but it has also its drawback as it’s a common cause of memory leaks in JavaScript applications.

The makeCounter() function above creates and returns another function that keeps track of the environment in which it’s created. Although the execution of makeCounter() is over when the variable counter is assigned, the local variable i is kept in displayCounter‘s closure, and can be therefore accessed inside its body.

If we were to run makeCounter again, it would create a new closure, with a different entry for i:

With this pattern, exploiting closures, we can create a wrapper for a property name, with our own setter and getter. ES5 made this a lot easier, since you can create objects with getters and setters for their properties, and control access to the properties themselves at the finest grain.

Closures in a Nutshell

The following table describes closure in Java, Python, and JavaScript:

Feature

Java

Python

JavaScript

Warnings

Closure

Weakened, read-only, in anonymous inner classes

Weakened, read-only, in nested def

Yes

Memory leaks

Memoization Pattern

Must use shared objects

Possible using lists or dictionaries

Yes

Better use lazy evaluation

Namespace/Module Pattern

Not needed

Not needed

Yes

Private Attributes Pattern

Not needed

Not possible

Yes

Might get confusing

Conclusion

In this article I covered three features of JavaScript that are often misunderstood by developers coming from different languages, especially Java and C. In particular, we’ve discussed concepts as scoping, hosting, functions, and closures. In case you want to study in deep these topics, here is a list of articles you can read:

I'm a full stack engineer with a passion for Algorithms and Machine Learning, and a soft spot for Python and JavaScript. I love coding as much as learning, and I enjoy trying new languages and patterns.

Just another JS article

Congratulations, You have just added another article to the interwebz that shows how mis-understood JavaScript is. Not because you showcase any knowledge at all ofcourse. Your examples are wrong (did you even bother checking them?) and I think you didn't even take the time to look up anything at all about the language.

A bad start:

Your first example is wrong. It does not output 'undefined, 0 5 5'. It does however output ' undefined 0 0'. This because thx to hoisting the proper equivalent is this:

Prototype, functional, potatoe, potato, whatever

You state that JavaScript is a functional language, kind of. Not really, it looks like one. So lets call it one. Or whatever.. Why force it to be anything else than what is really is? Why even try. It's a prototype based language, and that is really powerful!

You also state a few lines later that function is a primitive. But it's also an object. These two statements do not go well together. A quick fact checking on mdn would give us the following primitives:

string

number

Boolean

null

undefined

The mdn article also talks about primitive Wrappers. Objects that wrap around a primitive. This explains the behavior:

typeof new Number(5); //Object
typeof 5; //number

Strange use of language

Normally, in computer science, we use words like 'is a'. You don't, you say

Function, the type of functions, is built upon Object

Not sure what you mean here, simply put. A Function is an Object. This because it is not a primitive. You then go on to 'prove' this by doing a typeof function.prototype . Not sure what your point here is. You have proven that the prototype is an object. Wow.

You also state that functions (can) have properties. Not sure if this is such a special thing, it's an object...

And to explain closures, the following sentence does that really well: (taken from crockfords website)

An inner function always has access to the vars and parametersof its outer function, even after the outer function has returned.

Examples should explain

You end the article with some examples, not sure what they should prove. Your Person function is a factory-like function that returns an object that has access to a passed in variable 'thanks to' scope, closure, whatever. This doesn't make the variable private, It just makes the variable a memory-leak. The variable also has nothing to do with the object. The object consists simply of 2 functions that have access to a non-local variable. Your point? Personally, if you want to show how to create an object with private vars, use privileged functions:

For people who would like to have a good read on scope and stuff: crockford

EDIT: I just can't resist. You talk about JS being the first 'mainstream' language to implement closures. this shows that you or, have no idea what closures are, or with mainstream, you mean: 'that I know'. The fist language implementing closures was somewhere around 1970 (if I remember correct). I wasn't even born then...

You are right about the first example, there is a typo: if (false) was supposed to be if (true) on line 6.Although you are also right it is not acceptable, unfortunately typos and errors happens.Thanks for catching it and adding a walkthrough through the function, that I'm sure will help readers.

About your last example, using that syntax (creating an object with a constructor) is a perfectly valid alternative.Your example, however, is error prone, because if Person is called without new in front of it, undefined will be returned - which is the main turn off for constructors.This is easily solved, though:

By the way, you don't really need to declare another privateName var, since you can just use the argument to the constructor, which will as well captured in the get and set functions' closures.

I think you are making a bit of confused about the term "mainstream".I never claimed that JavaScript invented closures, but you can hardly say that Scheme was ever a mainstream language, while JavaScript is the first language having closures that is widely adopted.But you don't have to take my word on that, you seems to have enough confidence in Douglas Crockford to take his (browse a bit through his videos, will you?, and you'll find those exact same words).

Speaking of Crockford, thanks for the extra pointers, they will certainly be a wonderful reading/listening that I strongly suggest to every one.

this is not personal, if you feel it is a personal rant, it is not. It is just a frustrated dude who thinks he is the next #worldDominator vomiting words into a textbox.

I should advice everyone to look up your blog (I think it is yours) and read up on the really strong articles you have (I really mean this. I really like the topics you are addressing there and they are really well explained).

I think it is also safe to say that the examples you are using in this article are bad.. They do to much, using type-coercion in an example of hoisting simply adds to the confusion. That same example in fact demonstrates that hoisting really is: moving a var statement to the top of the function block. You should emphasize that.

I am also not at all convinced of your JS-knowledge, but it is hard to say something about that from one article - or comment.

Default return values

Functions always return a value. Always. If no return; is used, then the default value returned is undefined. If you use the new keyword, the default value returned is this.

Writing:

function Person() {};
var p = new Person();

Is the same as:

function Person() { return this; }
var p = Person();

Using your approach doesn't really fix anything, unless developer laziness counts as a problem that should be solved with code. Even worse, it helps writing hard-to-read code. We have a keyword to help us, so let's use it.

And no, I don't need to declare my privateName in my example. But think of code-readability. Think of variables that are not passed in in the constructor. Think of creating a clean example that shows one thing and one thing only. My example is used to illustrate how to create private variables with public getters and setters.

Hoisting, var, function and var function

You kind of make a point, but kind of miss the point as well when you talk about hoisting and stuff. In JavaScript all variables and function declarations are hoisted, simply put (as you correctly state) they are moved to the top of the current function block.

function foo() {
console.log(a); //undefined
var a = 5;
}
foo();

Is actually parsed as:

function foo() {
var a;
console.log(a); //undefined
a = 5;
}
foo();//after the function exits, a is garbage collected since we no longer reference it

But what happens if we forget to declare our variable all together?

function foo() {
console.log(a); //undefined
a = 5;
}
foo();

This roughly translates to:

var a;
function foo() {
console.log(a); //undefined
a = 5;
}
foo();

Our variable a is declared globally, not because it is hoisted, but simply because we forgot to declare it, and so JavaScript declares it globally for us, the true friend he is.And we now can no longer garbage collect our variable because it is global.

Then there is the difference between function declaration and function expression/statement. The first is hoisted, the latter not. But why is it hoisted? this has to with execution time. The JS-engine first parses our codezz and creates the execution context. This means declaring variables (and thus hosting them), parsing function declarations, ... The next phase is execution. He simple walks over line by line and executes it.

//this is evaluated on execution-time
foo();
//the named function is created on parse-time, and thus hoisted
function foo() {
console.log('foobar');
}

The following however will not work:

foo();
var foo = function foo() {console.log('foobar');}

This because it translates to:

var foo; //the declaration of our variable is hoisted
foo(); //but it is still undefined here
foo = function foo() {console.log('foobar');} //here we assign a function expression to the variable.

Our function expression is only parsed on execution-time instead of parse time. #confusion <- this hashtag exists purely for JavaScript

Totally right about constructors and return type. Thanks for giving me the chance to talk about this a bit more.Indeed, what I see as the very problem with new and constructors, is the peculiar behavior of 1) The this pointer2) The return typefor constructors.

You yourself, in the rush of the moment, are making a bit of confusion in your counter example:

Back to your example, for sake of completeness, say we use an explicit return statement (return this;), what is going to be returned when we use var p = Person('foo') (without new)?Not a new Person, of course, nor undefined.To let everybody else understand: since when we call a function as a function (i.e. not as a method, constructor or by using apply/call) this is set to the global object, then window (in browsers, ofc) is returned.If we use strict mode however, this will be set to null instead, and an error will be thrown this.getName = ....

Now, on the other hand, by using that safe constructor pattern,

if (!(this instanceof Person)) {
return new Person(name);
}

a Person object will be returned both in strict mode (ES5 and newer versions) and "legacy" mode, no matter if the caller uses new or forgets about it.That's why this pattern is safe, and the other is error prone.

Now, JavaScript allows you to do the same thing in many different ways, and one is free to like enforcing the use of constructors and new.Personally, I think this is trying to make it more similar to Java, and in fact it astray you from the prototypical pattern in favor to something similar to the class pattern.

You are also totally free not to care about lazy programmers, and just hope they never forget to prepend new to your library's constructors. But I guess it is good to know you have an easy alternative to make your code more robust - personally I like that.

Again, you all don't take have to take my word on that: Crockford himself advice against the use of constructors in his videos and his book (Javascript: the good parts - new is actually included in the bad parts), and you can check another great book, Javascript Patterns by Stefanov for the safe constructor pattern.

To complete the discussion about this example, the reader should be aware that either reusing the function parameter or declaring a private var inside Person and assigning the parameter to it, in both cases this value will be kept private only if it is an immutable value (a primitive). If something is it is an object or an array (so essentially something passed by reference and not by value), it will still be possible to modify it outside of the function, because assignment only perform shallow copy.

To avoid this, you need to make a deep copy of the parameter you get (to this end, declaring a privateName field, although not stricly necessary, helps for clarity and readability, agreed on that).For instance, you could try something on the line of:

To let everybody else understand: since when we call a function as a function (i.e. not as a method, constructor or by using apply/call) this is set to the global object, then window (in browsers, ofc) is returned.

Many of the JavaScript built in functions/objects make use of the difference between calling them using new and calling them without.

For example:

today1 = Date();
today2 = (new Date()).toLocaleString();

the first of these is calling the Date() function to return today's date in whatever format your browser is set to use while the second of these creates a Date() object and then uses a method on that object to return today's date in whatever format your browser is set to use.

Similar function/object pairs exist for Boolean() Number() and String() where the function converts whatever is passed to it to the appropriate primitive data type while the object call (with new) creates an object of that type (which is not the same type as the primitive that the function returns).

I think the article had two issue, one of which was a simple typo. Based on that, I think your reply was a bit too hard for what is, in my opinion, only one real error.

First error outlined is that the first snippet doesn't work properly. This was because the "if (false)" was actually an "if (true)". You seem to understand JavaScript enough to easily spot that this was just a typo. So, perhaps, instead of writing 15 lines of text claiming how bad was the code and the article, I think you could have simply written: "Hey dude, there's a typo in your article". It'd have been more than enough. As a long-time writer (~130 articles to date) I have made a lot of such typos because it simply happens (as the author himself replied).

Second error is more severe and I apologize for that as the reviewer. The error is: "functions are a primitive type in JavaScript." This is of course wrong and I've fixed the text.

Just to make it even more clear how your comment was too hard, I want to highlight this point:

You talk about JS being the first 'mainstream' language to implement closures. this shows that you or, have no idea what closures are, or with mainstream, you mean: 'that I know'. The fist language implementing closures was somewhere around 1970 (if I remember correct). I wasn't even born then...

Keeping in mind that mainstream languages today are pretty much JavaScript, Java, PHP, C#, C/C++, and Ruby, why asserting that JS has closures and is mainstream is wrong? To me this seems absolutely true. If you consider some old fashion language from the '70 as mainstream today, it's fine. However, I'm pretty sure that most developers would agree with that statement.

Another example of how you overreacted:

You also state that functions (can) have properties. Not sure if this is such a special thing, it's an object...

In JS functions are object and the author is targeting people coming from Java and C. Therefore completely beginners. With this in mind, isn't explicitly asserting that functions can have properties worth mention? I thinks so.Moreover, few days ago I was explaining exactly this concept to a friend of mine who is a pure Java developer and it's just approaching JavaScript. He was shocked twice. The first time when I explained to him that functions in JavaScript are objects. The second time when I highlighted that because functions are objects they can have properties. If you, thanks to your knowledge, don't find this concepts shocking then fine. But don't assume that other developers wouldn't benefit from it.

So, in conclusion, thank you for the two points but I think your reply was a bit exaggerated.

Exactly, that's a very good point.In all those cases, though, these functions actively handle the case when you don't call them as constructors.Personally I think that, especially for Date, this is not the clearest design (maybe f.i. a Number.tonum method would have been as effective?) but chances that it leads to unexpected behavior are quite low indeed.

Good article. Thanks for the effort, just please proofread or have someone proofread before publishing. The grammatical errors and choice of wrong words takes away the reader's focus and makes it hard to get through.Other than that drive on!!