One of the secrets of an effective JavaScript developer is a deep understanding of the semantics of a language. In this article I will explain the basic elementary parts of the language, using the most simple and understandable diagrams.
Everywhere links
A JavaScript variable is simply a name indicating a value stored somewhere in memory. These values can be either primitives (strings, integers, booleans), or objects or functions.
Local variables
In the following example, we will create four local variables in the highest level
scope and point them to some primitive values:
')
Output=> true
Notice that the two variables point to the same value in memory. This happens because primitives are immutable and the virtual machine can use a single instance of the object for all variable references that point to this value.
In the example above, we checked whether the two references point to the same value using the
=== operator and get the confirmation
true .
The box on the left in the diagram is the outermost closed area of visibility (
closure scope ). The variables in it are local variables of the highest level, it is important not to confuse them with the properties of the
global / window object.
Prototype Objects and Chains
Objects are simply sets of references to other objects and prototypes. The only difference is the addition of a prototype chain (
prototype chain ) to gain access to properties that are not in the local object, but in the parent.
Output=> true
Here we have one object with four properties referenced by the variable
tim . We also created a new object that inherits the first one and reference the variable
jack to it . After that we rewrite two properties in the local object.
Now, if we start looking for the
jack.likesJavaScript property, we first find the object pointed to by
jack . Next, look for the
likesJavaScript property. Since it is not there, we look at the parent object and find it there and get the value
true , which this property refers to.
Global object
If you have ever wondered why tools like
jslint are always advised not to forget to put a
var expression before declaring a variable, this is what happens otherwise:
var name = "Tim Caswell"; var age = 28; var isProgrammer = true;

Note that
likesJavaScript is now a property of a global object, instead of being a free variable in the outer closed scope. It matters only when you mix several scripts. But in real programs, this is exactly what you are going to do, isn't it?
Remember: always put
var expressions to hold the variable in the current and child closed scopes.
If you need to put something in a global object, do it on purpose, using
window.woo in a browser or
global.woo in node.js
Functions and scopes
JavaScript is not just a collection of related data structures. It contains executable, callable code, known as functions. Functions create related visibility and closures.
Closure visualization
The function can be represented as a special object containing not only properties, but also executable code. Each function has a special
[scope] property, which represents the environment in which the function was located at the time of the declaration. If the function is returned from another function, then this is the link to the environment from which it was returned “closed” by a new function to the “closure”.
In this example, we will create a simple factory method that generates a closure and returns a function.
function makeClosure(name) { return function () { return name; }; } var description1 = makeClosure("Cloe the Closure"); var description2 = makeClosure("Albert the Awesome"); console.log(description1()); console.log(description2());
OutputCloe the Closure Albert the Awesome
When we call
description1 (), the virtual machine looks for the function on this link and executes it. This function searches for a local variable named
name and finds it in a closed scope. This factory method is good because each generated function has its own scope for local variables.
If you want to learn more about closures, see my article
Why use closure .
General functions and this
Sometimes for production reasons or preferences in programming style, common (
shared ) functions are used that allow the same function to be used in different scopes using the
this keyword .
Create a pair of objects that share a common function. In this function, pointers to
this will be used to show the difference.
var Lane = { name: "Lane the Lambda", description: function () { return this.name; } }; var description = Lane.description; var Fred = { description: Lane.description, name: "Fred the Functor" };
OutputLane the Lambda Fred the Functor undefined Zed the Zetabyte
In this diagram, we see that although
Fred.description was assigned to the
Lane.description , it is just a reference to the function. Thus, all three links point to one common anonymous function. That is why I try not to call functions in prototype constructors "methods"; this can be misleading about some binding of the function to the designer and its "class".
If you want to learn more about
this , see
what is this article in my article. If it is interesting, I will translate this article as well.
Conclusion
Hopefully this will help JavaScript students understand more deeply the semantics of the language. In the past, I was both a client developer / designer and server architect, so I chose a special visual explanation path.
Original article by Tim Caswell:
howtonode.org/object-graphsFrom the translator: this is my first article and translation in Habré, the whole cycle of articles itself seemed very useful. The author has two more parts and many other materials on the website howtonode.org . If there are inaccuracies or amendments, I will correct it. Not quite sure about the correctness of the closure (closure) and scope (space) translation, maybe someone has better versions? If it is interesting, I will translate the remaining two parts.UPD: Corrected typos, put code examples in order and, on the advice of ilya42, replaced “spaces” with more correct “scopes”.