What does ==$0 (double equals dollar zero) mean in Chrome Developer Tools?
In Google Chrome’s developer tools, when I select an element, I see ==$0 next to the selected element. What does that mean?

![]()
![]()
5 Answers 5
It’s the last selected DOM node index. Chrome assigns an index to each DOM node you select. So $0 will always point to the last node you selected, while $1 will point to the node you selected before that. Think of it like a stack of most recently selected nodes.
As an example, consider the following
Now you opened the devtools console and selected #sunday , #monday and #tuesday in the mentioned order, you will get ids like:
Note: It Might be useful to know that the node is selectable in your scripts (or console), for example one popular use for this is angular element selector, so you can simply pick your node, and run this:
Хитрый вопрос по JavaScript, который задают на собеседованиях в Google и Amazon
Привет Хабр! Есть один вопрос, с виду — не такой уж и сложный, который нередко задают разработчикам на собеседованиях.
Сегодня мы его разберём и поговорим о подходах к поиску ответа. Задавая вопрос, о котором идёт речь, интервьюер предлагает рассказать о том, что выведет примерно такой код:
А вы знаете, что появится в консоли?
Сразу хочется сказать, что этот вопрос направлен на понимание таких механизмов JS, как замыкания, области видимости и функция setTimeout. Правильный ответ выглядит так:
Если вы ожидали чего-то другого, надеемся, в этом материале мы сможем рассказать о том, почему вывод этого фрагмента кода оказался именно таким, и о том, как привести его в более приличный вид.
Почему этот вопрос так популярен?
Один пользователь Reddit рассказал о том, что ему задавали такой вопрос на собеседовании в Amazon. Я и сам сталкивался с подобными вопросами, направленными на понимание циклов и замыканий в JS, даже на собеседовании в Google.
Этот вопрос позволяет проверить владение некоторыми важными концепциями JavaScript. Учитывая особенности работы JS, ситуация, которая смоделирована в представленном фрагменте кода, нередко может возникать и в ходе реальной работы. В частности, это касается использования setTimeout или какой-нибудь другой асинхронной функции в цикле.
Хорошее понимание функциональных и блочных областей видимости в JavaScript, особенностей устройства анонимных функций, замыканий и IIFE, поможет вашему профессиональному росту и позволит показать себя с хорошей стороны на собеседованиях.
Подходы к ответу на вопрос и к избавлению от undefined
На самом деле, я уже писал о возможных подходах к ответу на этот вопрос в некоторых моих предыдущих материалах. В частности, в этом и этом. Позволю себе процитировать кое-что из этих публикаций:
Причина подобного заключается в том, что функция setTimeout создаёт функцию (замыкание), у которой есть доступ к внешней по отношению к ней области видимости, представленной в данном случае циклом, в котором объявляется и используется переменная i . После того, как пройдут 3 секунды, функция выполняется и выводит значение i , которое, после окончания работы цикла, остаётся доступным и равняется 4-м. Переменная, в ходе работы цикла, последовательно принимает значения 0, 1, 2, 3, 4, причём, последнее значение оказывается сохранённым в ней и после выхода из цикла. В массиве имеется четыре элемента, с индексами от 0 до 3, поэтому, попытавшись обратиться к arr[4] , мы и получаем undefined . Как избавиться от undefined и сделать так, чтобы код выводил то, чего от него и ждут, то есть — значения элементов массива?
Вот пара распространённых подходов к решению подобной задачи, а конкретно — к тому, чтобы организовать доступ к нужному значению переменной цикла внутри функции, вызываемой setTimeout .
Первый предусматривает передачу необходимого параметра во внутреннюю функцию, второй основан на использовании возможностей ES6.
Итак, вот первый вариант:
Вот второй вариант:
На Reddit мне удалось найти похожий ответ на этот вопрос. Вот — хорошее разъяснение особенностей замыканий на StackOverflow.
Итоги
Можно отметить, что вопрос, с которого мы начали этот материал, часто сбивает с толку людей, обладающих небольшим опытом в области JavaScript или в функциональном программировании. Причина заключается в непонимании сущности замыканий. При формировании замыкания не выполняет передача значения переменной или ссылки на неё. Замыкание захватывает саму переменную.
Уважаемые читатели! Знаете ли вы интересные вопросы, которые задают на собеседованиях по JavaScript? Если да — просим поделиться.
Grammar and types
This chapter discusses JavaScript’s basic grammar, variable declarations, data types and literals.
Basics
JavaScript borrows most of its syntax from Java, C, and C++, but it has also been influenced by Awk, Perl, and Python.
JavaScript is case-sensitive and uses the Unicode character set. For example, the word Früh (which means «early» in German) could be used as a variable name.
But, the variable früh is not the same as Früh because JavaScript is case sensitive.
In JavaScript, instructions are called statements and are separated by semicolons (;).
A semicolon is not necessary after a statement if it is written on its own line. But if more than one statement on a line is desired, then they must be separated by semicolons.
Note: ECMAScript also has rules for automatic insertion of semicolons (ASI) to end statements. (For more information, see the detailed reference about JavaScript’s lexical grammar.)
It is considered best practice, however, to always write a semicolon after a statement, even when it is not strictly needed. This practice reduces the chances of bugs getting into the code.
The source text of JavaScript script gets scanned from left to right, and is converted into a sequence of input elements which are tokens, control characters, line terminators, comments, or whitespace. (Spaces, tabs, and newline characters are considered whitespace.)
Comments
The syntax of comments is the same as in C++ and in many other languages:
Comments behave like whitespace, and are discarded during script execution.
Note: You might also see a third type of comment syntax at the start of some JavaScript files, which looks something like this: #!/usr/bin/env node .
This is called hashbang comment syntax, and is a special comment used to specify the path to a particular JavaScript engine that should execute the script. See Hashbang comments for more details.
Declarations
JavaScript has three kinds of variable declarations.
Declares a variable, optionally initializing it to a value.
Declares a block-scoped, local variable, optionally initializing it to a value.
Declares a block-scoped, read-only named constant.
Variables
You use variables as symbolic names for values in your application. The names of variables, called identifiers, conform to certain rules.
A JavaScript identifier must start with a letter, underscore ( _ ), or dollar sign ( $ ). Subsequent characters can also be digits ( 0 – 9 ).
Because JavaScript is case sensitive, letters include the characters » A » through » Z » (uppercase) as well as » a » through » z » (lowercase).
You can use most of ISO 8859-1 or Unicode letters such as å and ü in identifiers. (For more details, see this blog post.) You can also use the Unicode escape sequences as characters in identifiers.
Some examples of legal names are Number_hits , temp99 , $credit , and _name .
Declaring variables
You can declare a variable in two ways:
- With the keyword var . For example, var x = 42 . This syntax can be used to declare both local and global variables, depending on the execution context.
- With the keyword const or let . For example, let y = 13 . This syntax can be used to declare a block-scope local variable. (See Variable scope below.)
You can declare variables to unpack values from Object Literals using the Destructuring Assignment syntax. For example, let < bar >= foo . This will create a variable named bar and assign to it the value corresponding to the key of the same name from our object foo .
You can also assign a value to a variable. For example, x = 42 . This form creates an undeclared global variable. It also generates a strict JavaScript warning. Undeclared global variables can often lead to unexpected behavior. Thus, it is discouraged to use undeclared global variables.
Evaluating variables
A variable declared using the var or let statement with no assigned value specified has the value of undefined .
An attempt to access an undeclared variable results in a ReferenceError exception being thrown:
You can use undefined to determine whether a variable has a value. In the following code, the variable input is not assigned a value, and the if statement evaluates to true .
The undefined value behaves as false when used in a boolean context. For example, the following code executes the function myFunction because the myArray element is undefined :
The undefined value converts to NaN when used in numeric context.
When you evaluate a null variable, the null value behaves as 0 in numeric contexts and as false in boolean contexts. For example:
Variable scope
When you declare a variable outside of any function, it is called a global variable, because it is available to any other code in the current document. When you declare a variable within a function, it is called a local variable, because it is available only within that function.
JavaScript before ECMAScript 2015 does not have block statement scope. Rather, a variable declared within a block is local to the function (or global scope) that the block resides within.
For example, the following code will log 5 , because the scope of x is the global context (or the function context if the code is part of a function). The scope of x is not limited to the immediate if statement block.
This behavior changes when using the let declaration (introduced in ECMAScript 2015).
Variable hoisting
Another unusual thing about variables in JavaScript is that you can refer to a variable declared later, without getting an exception.
This concept is known as hoisting. Variables in JavaScript are, in a sense, «hoisted» (or «lifted») to the top of the function or statement. However, variables that are hoisted return a value of undefined . So even if you declare and initialize after you use or refer to this variable, it still returns undefined .
The above examples will be interpreted the same as:
Because of hoisting, all var statements in a function should be placed as near to the top of the function as possible. This best practice increases the clarity of the code.
In ECMAScript 2015, let and const are hoisted but not initialized. Referencing the variable in the block before the variable declaration results in a ReferenceError , because the variable is in a «temporal dead zone» from the start of the block until the declaration is processed.
Function hoisting
Functions are hoisted if they’re defined using function declarations — but functions are not hoisted if they’re defined using function expressions.
The following example shows how, due to function hoisting, the function foo can be called even before it’s defined — because the foo function is defined using a function declaration.
In the following example, the variable name baz is hoisted — due to variable hoisting — but because a function is assigned to baz using a function expression rather than baz being defined with a function declaration, the function can’t be called before it’s defined, because it’s not hoisted.
Thus, the baz() call below throws a TypeError with “baz is not a function”, because the function assigned to baz isn’t hoisted — while the console.log(baz) call doesn’t throw a ReferenceError but instead logs undefined , because the variable baz is still hoisted even though the function assigned to it isn’t. (But the value of baz is undefined, since nothing has yet been assigned to it).
Global variables
Global variables are in fact properties of the global object.
In web pages, the global object is window , so you can set and access global variables using the window.variable syntax.
Consequently, you can access global variables declared in one window or frame from another window or frame by specifying the window or frame name. For example, if a variable called phoneNumber is declared in a document, you can refer to this variable from an iframe as parent.phoneNumber .
Constants
You can create a read-only, named constant with the const keyword.
The syntax of a constant identifier is the same as any variable identifier: it must start with a letter, underscore, or dollar sign ( $ ), and can contain alphabetic, numeric, or underscore characters.
A constant cannot change value through assignment or be re-declared while the script is running. It must be initialized to a value.
The scope rules for constants are the same as those for let block-scope variables. If the const keyword is omitted, the identifier is assumed to represent a variable.
You cannot declare a constant with the same name as a function or variable in the same scope. For example:
However, the properties of objects assigned to constants are not protected, so the following statement is executed without problems.
Also, the contents of an array are not protected, so the following statement is executed without problems.
Data structures and types
Data types
The latest ECMAScript standard defines eight data types:
- Seven data types that are primitives:
-
. true and false . . A special keyword denoting a null value. (Because JavaScript is case-sensitive, null is not the same as Null , NULL , or any other variant.) . A top-level property whose value is not defined. . An integer or floating point number. For example: 42 or 3.14159 . . An integer with arbitrary precision. For example: 9007199254740992n . . A sequence of characters that represent a text value. For example: «Howdy» (new in ECMAScript 2015). A data type whose instances are unique and immutable.
- and Object
Although these data types are relatively few, they enable you to perform useful functions with your applications. Objects and functions are the other fundamental elements in the language. You can think of objects as named containers for values, and functions as procedures that your script can perform.
Data type conversion
JavaScript is a dynamically typed language. This means you don’t have to specify the data type of a variable when you declare it. It also means that data types are automatically converted as-needed during script execution.
So, for example, you could define a variable as follows:
And later, you could assign the same variable a string value, for example:
Because JavaScript is dynamically typed, this assignment does not cause an error message.
Numbers and the ‘+’ operator
In expressions involving numeric and string values with the + operator, JavaScript converts numeric values to strings. For example, consider the following statements:
With all other operators, JavaScript does not convert numeric values to strings. For example:
Converting strings to numbers
In the case that a value representing a number is in memory as a string, there are methods for conversion.
parseInt only returns whole numbers, so its use is diminished for decimals.
Note: Additionally, a best practice for parseInt is to always include the radix parameter. The radix parameter is used to specify which numerical system is to be used.
An alternative method of retrieving a number from a string is with the + (unary plus) operator:
Literals
Literals represent values in JavaScript. These are fixed values—not variables—that you literally provide in your script. This section describes the following types of literals:
Array literals
An array literal is a list of zero or more expressions, each of which represents an array element, enclosed in square brackets ( [] ). When you create an array using an array literal, it is initialized with the specified values as its elements, and its length is set to the number of arguments specified.
The following example creates the coffees array with three elements and a length of three:
Note: An array literal is a type of object initializer. See Using Object Initializers.
If an array is created using a literal in a top-level script, JavaScript interprets the array each time it evaluates the expression containing the array literal. In addition, a literal used in a function is created each time the function is called.
Note: Array literals are also Array objects. See Array and Indexed collections for details on Array objects.
Extra commas in array literals
If you put two commas in a row in an array literal, the array leaves an empty slot for the unspecified element. The following example creates the fish array:
When you log this array, you will see:
Note that the second item is «empty», which is not exactly the same as the actual undefined value. When using array-traversing methods like Array.prototype.map , empty slots are skipped. However, index-accessing fish[1] still returns undefined .
If you include a trailing comma at the end of the list of elements, the comma is ignored.
In the following example, the length of the array is three. There is no myList[3] . All other commas in the list indicate a new element.
In the following example, the length of the array is four, and myList[0] and myList[2] are missing.
In the following example, the length of the array is four, and myList[1] and myList[3] are missing. Only the last comma is ignored.
Note: Trailing commas help keep git diffs clean when you have a multi-line array, because appending an item to the end only adds one line, but does not modify the previous line.
Understanding the behavior of extra commas is important to understanding JavaScript as a language.
However, when writing your own code, you should explicitly declare the missing elements as undefined , or at least insert a comment to highlight its absence. Doing this increases your code’s clarity and maintainability.
Boolean literals
The Boolean type has two literal values: true and false .
Note: Do not confuse the primitive Boolean values true and false with the true and false values of the Boolean object.
The Boolean object is a wrapper around the primitive Boolean data type. See Boolean for more information.
Numeric literals
JavaScript numeric literals include integer literals in different bases as well as floating-point literals in base-10.
Note that the language specification requires numeric literals to be unsigned. Nevertheless, code fragments like -123.4 are fine, being interpreted as a unary — operator applied to the numeric literal 123.4 .
Integer literals
Integer and BigInt literals can be written in decimal (base 10), hexadecimal (base 16), octal (base 8) and binary (base 2).
- A decimal integer literal is a sequence of digits without a leading 0 (zero).
- A leading 0 (zero) on an integer literal, or a leading 0o (or 0O ) indicates it is in octal. Octal integer literals can include only the digits 0 – 7 .
- A leading 0x (or 0X ) indicates a hexadecimal integer literal. Hexadecimal integers can include digits ( 0 – 9 ) and the letters a – f and A – F . (The case of a character does not change its value. Therefore: 0xa = 0xA = 10 and 0xf = 0xF = 15 .)
- A leading 0b (or 0B ) indicates a binary integer literal. Binary integer literals can only include the digits 0 and 1 .
- A trailing n suffix on an integer literal indicates a BigInt literal. The integer literal can use any of the above bases. Note that leading-zero octal syntax like 0123n is not allowed, but 0o123n is fine.
Some examples of integer literals are:
Floating-point literals
A floating-point literal can have the following parts:
- An unsigned decimal integer,
- A decimal point (» . «),
- A fraction (another decimal number),
- An exponent.
The exponent part is an » e » or » E » followed by an integer, which can be signed (preceded by » + » or » — «). A floating-point literal must have at least one digit, and either a decimal point or » e » (or » E «).
More succinctly, the syntax is:
Object literals
An object literal is a list of zero or more pairs of property names and associated values of an object, enclosed in curly braces ( <> ).
Warning: Do not use an object literal at the beginning of a statement! This will lead to an error (or not behave as you expect), because the < will be interpreted as the beginning of a block.
The following is an example of an object literal. The first element of the car object defines a property, myCar , and assigns to it a new string, » Saturn «; the second element, the getCar property, is immediately assigned the result of invoking the function (carTypes(«Honda»)) ; the third element, the special property, uses an existing variable ( sales ).
Additionally, you can use a numeric or string literal for the name of a property or nest an object inside another. The following example uses these options.
Object property names can be any string, including the empty string. If the property name would not be a valid JavaScript identifier or number, it must be enclosed in quotes.
Property names that are not valid identifiers cannot be accessed as a dot ( . ) property, but can be accessed and set with the array-like notation(» [] «).
Enhanced Object literals
In ES2015, object literals are extended to support setting the prototype at construction, shorthand for foo: foo assignments, defining methods, making super calls, and computing property names with expressions.
Together, these also bring object literals and class declarations closer together, and allow object-based design to benefit from some of the same conveniences.
RegExp literals
A regex literal (which is defined in detail later) is a pattern enclosed between slashes. The following is an example of a regex literal.
String literals
A string literal is zero or more characters enclosed in double ( » ) or single ( ‘ ) quotation marks. A string must be delimited by quotation marks of the same type (that is, either both single quotation marks, or both double quotation marks).
The following are examples of string literals:
You should use string literals unless you specifically need to use a String object. See String for details on String objects.
You can call any of the String object’s methods on a string literal value. JavaScript automatically converts the string literal to a temporary String object, calls the method, then discards the temporary String object. You can also use the String.length property with a string literal:
Template literals are also available. Template literals are enclosed by the back-tick ( ` ) (grave accent) character instead of double or single quotes.
Template literals provide syntactic sugar for constructing strings. (This is similar to string interpolation features in Perl, Python, and more.)
Tagged templates are a compact syntax for specifying a template literal along with a call to a «tag» function for parsing it; the name of the template tag function precedes the template literal — as in the following example, where the template tag function is named » myTag «:
Using special characters in strings
In addition to ordinary characters, you can also include special characters in strings, as shown in the following example.
The following table lists the special characters that you can use in JavaScript strings.
| Character | Meaning |
|---|---|
| \0 | Null Byte |
| \b | Backspace |
| \f | Form feed |
| \n | New line |
| \r | Carriage return |
| \t | Tab |
| \v | Vertical tab |
| \’ | Apostrophe or single quote |
| \» | Double quote |
| \\ | Backslash character |
| \XXX | The character with the Latin-1 encoding specified by up to three octal digits XXX between 0 and 377 . For example, \251 is the octal sequence for the copyright symbol. |
| \xXX | The character with the Latin-1 encoding specified by the two hexadecimal digits XX between 00 and FF . For example, \xA9 is the hexadecimal sequence for the copyright symbol. |
| \uXXXX | The Unicode character specified by the four hexadecimal digits XXXX. For example, \u00A9 is the Unicode sequence for the copyright symbol. See Unicode escape sequences. |
| \u | Unicode code point escapes. For example, \u <2F804>is the same as the simple Unicode escapes \uD87E\uDC04 . |
Escaping characters
For characters not listed in the table, a preceding backslash is ignored, but this usage is deprecated and should be avoided.
You can insert a quotation mark inside a string by preceding it with a backslash. This is known as escaping the quotation mark. For example:
The result of this would be:
To include a literal backslash inside a string, you must escape the backslash character. For example, to assign the file path c:\temp to a string, use the following:
You can also escape line breaks by preceding them with backslash. The backslash and line break are both removed from the value of the string.
Although JavaScript does not have «heredoc» syntax, you can get close by adding a line break escape and an escaped line break at the end of each line:
ECMAScript 2015 introduces a new type of literal, namely template literals. This allows for many new features, including multiline strings!
More information
This chapter focuses on basic syntax for declarations and types. To learn more about JavaScript’s language constructs, see also the following chapters in this guide:
In the next chapter, we will have a look at control flow constructs and error handling.