In JavaScript, you can declare a variable using the var, let, or const keyword.
Assignment is the process of giving a value to a declared variable.
// When you declare variable without initializing it, the variable is automatically assigned value undefined. var someVariable; let anotherVariable; // const variables must always be initialized with value, and their value cannot be changed afterward. const PI = 3.14159; const specificNumber = 10; // most basic assignment operator is equals sign (=) someVariable = 'any word'; // There are also compound operators, which perform operation and assign result to variable in single step. let sn = 20; sn += 13; // => 33 - equivalent to sn = sn + 13; sn -= 9; // => 24 - equivalent to sn = sn - 9; sn *= 2; // => 48 equivalent to sn = sn * 2; sn /= 6; // => 8 - equivalent to sn = sn / 6; sn %= 5; // => 3 - equivalent to sn = sn % 5;
Variables that hold non-primitive data types (such as objects and arrays) are assigned by reference, while variables that hold primitive data types (such as numbers, strings, and booleans) are assigned by value.
When a variable is assigned by reference, it stores a reference to the memory location where the value is stored, rather than the value itself. This can have implications when modifying the value of the variable.
In JS, you can declare a variable with the same name multiple times within the same scope using the var keyword. However, this is generally considered a bad practice and can lead to unexpected behavior. The later declaration will simply override the previous declaration, which can cause confusion and bugs.
In contrast, when using let or const to declare variables, you cannot redeclare a variable with the same name within the same block of code.
Shadowing occurs when a variable declared within a certain scope has the same name as a variable declared in an outer scope. The inner variable will "shadow" the outer variable, making it inaccessible within that scope.
let someDigit = 25; function foo() { let someDigit = 30; // inner variable shadows outer variable console.log(someDigit); // => 30 } foo(); console.log(someDigit); // => 25 - outer variable is still accessible outside of function
Temporal Dead Zone (TDZ) - behavior in JS that prevents variables from being accessed before they are declared.
If you try to access a let or const variable before its declaration, you will get a ReferenceError: is not defined.
When naming variables, you should follow certain conventions:
- variable names are case-sensitive;
- can contain letters, numbers, and underscores;
- must start with a letter or an underscore;
- use camelCase or snake_case for variable names;
- choose descriptive names that convey the purpose of the variable;
- important to avoid using reserved keywords.
It is a sequence of characters that represent text, and it is enclosed in either single quotes (' '), double quotes (" "), or backticks ( ).
concatenate (combine) strings
let firstName = "John"; let lastName = "Doe"; let fullName = firstName + " " + lastName; // => "John Doe"get the length of a string
let message = "A wonderful spring day!"; let messageLength = message.length; // => 23access individual characters in a string
let firstCharacter = message[0]; // => "A" let fifthCharacter = message[4]; // => "n"
JS provides many built-in methods for manipulating strings.
let phrase = 'It will be a warm Spring!'; phrase.toUpperCase(); // => ''IT WILL BE A WARM SPRING!'' phrase.toLowerCase(); // => ''it will be a warm spring!'' // check if string contains searchValue and returns boolean phrase.includes("warm"); // => true phrase.includes("cold"); // => false // check if string starts or ends with searchValue respectively phrase.startsWith('It will be'); // => true phrase.endsWith('warm spring!'); // => true // index of first occurrence of searchValue within string // it returns -1 if the value is not found phrase.indexOf('be'); // => 8 phrase.substring(3, 10); // => 'will be' // returns character at specified index in string let characterAtIndex11 = phrase.charAt(11); // => 'a'
Let's consider a few more manipulations with the text.
Note: It's important to understand that strings in JavaScript are immutable, which means that string methods do not modify the original string, but instead return a new string with the desired changes.
let stringo = 'A great man does great things on great days.'; // split string into array of substrings based on specified separator const arrPhrase = stringo.split(' '); // => ['A', 'great', 'man', 'does', 'great', 'things', 'on', 'great', 'days.'] // concatenate two or more strings and returns new string let citation = 'Citation:'; let fullPhrase = citation.concat(" ", stringo); fullPhrase; // => 'Citation: A great man does great things on great days.' // searchValue can be string or regExp, and replaceValue can be string or function stringo.replaceAll('great', 'small'); // => 'A small man does small things on small days.' // startIndex is inclusive, while endIndex is exclusive stringo.slice(8, 23); // => 'man does great ' // If endIndex is omitted, extraction continues to end of string. // Negative indices: -1 refers to last character, -2 refers to second-to-last character
A tag template is a loggerTag function that allows you to parse a template string.
There are several commonly used methods in JS for working with numbers.
Number.isFinite (constNum);Number.isFinite (17); // => true if a number was passed to it during the call Number.isFinite ('17'); // => false if a special value or non-numeric type is passed
constNum.toString(2);- converts a number to a string in the specified number systemlet constNum = 29; constNum.toString(2); // => '11101'
constNum.toFixed(2)- converts a number to a string with the specified number of decimal placeslet constNum = 16.5492; constNum.toFixed(2) // => '16.55'
- they convert the string character by character as long as possible
Number.parseInt('123boxes', 10); // => 123 Number.parseFloat('27.16% market share'); // => 27.16
Math.round(num);- normal roundingMath.ceil(num);- rounding to the topMath.floor(num);- rounding to the smaller sideMath.floor(Math.random() * (max - min)) + min;- generate a random number in a rangeMath.floor(Math.random() * array.length);- generate a random array elementMath.max(num1, num2, ...);- returns the largest integer in the setMath.min(num1, num2, ...);- returns the smallest number in the set
They are a data type in JavaScript that represent two values: true and false. They are used to represent binary logic, where something can be either true or false. Booleans are often used in conditional statements and comparisons to determine the flow of a program.
All values are truthy except for a few specific cases that are considered falsy 0, NaN, null, undefined, false, and empty strings ('').
In JS, null and undefined are special values that represent the absence of a value. When you assign null to a variable, you are explicitly setting it to have no value. When a variable is declared but not assigned any value, it is automatically assigned the value undefined.
It's important to note that null and undefined are distinct values in JS, and they are not interchangeable. null is a deliberate assignment to indicate the absence of a value, whereas undefined typically indicates that a value is missing or has not been assigned.\
nullis of type object, whereasundefinedis of type undefined
It is unique data type introduced in ES6 that represents unique identifier that is not equal to any other value, including other Symbol values.
Here are some common use cases of Symbol in real projects:
Symbol values can be used as property keys in JS objects to create non-enumerable properties.
This can be useful for creating hidden or internal properties that should not be exposed in certain use cases.const mySymbol = Symbol('mySymbol'); const myObj = { [mySymbol]: 'It is a non-enumerable property', foo: 'This is an enumerable property' }; console.log( Object.getOwnPropertySymbols(myObj) ); // => [Symbol(mySymbol)]When creating symbol, you can give a description (so-called name), which is mainly used to debug code:
let id = Symbol("idento"); console.log(id.description); // => identoThey create "hidden" properties of objects that cannot be accidentally accessed and overwritten from other parts of the program.
let usero = { name: "potatoGrower", [id]: 123, town: "Lynovo" }; // Properties whose keys are symbols are not iterated over by the for..in loop. let clone = Object.assign({}, usero); // clones all types of object properties;
Symbol.iterator- allows in constructions usingfor..ofand spread syntax...;Symbol.for(key)— returns the symbol stored by the key;
It refers to the accessibility and visibility of a variable within a certain portion of code during runtime.
It determines where a variable can be accessed and modified within a program.
- global scope
- variables declared outside of any function or block;
- can be accessed from anywhere within the program;
- should be used with caution as they can be modified by any part of program;
- local scope
- variables declared inside a function;
- can only be accessed from within function in which they are declared;
- allow to store temporary values that are only needed within particular function;
- function scope
- is similar to local scope, but it includes nested functions;
- block scope
- variables declared inside a block, such as loop or if statement;
- can only be accessed within block in which they are declared;
- was introduced in ES6 with let and const keywords;
const globalVariable = "I'm a global variable"; function outerFunction() { const outerVariable = "I'm an outer variable"; if (true) { let blockVariable = "I'm a block variable"; const anotherBlockVariable = "I'm another block variable"; console.log(blockVariable); // Output: "I'm a block variable" console.log(anotherBlockVariable); // Output: "I'm another block variable" } function innerFunction() { let innerVariable = "I'm an inner variable"; console.log(globalVariable); // Output: "I'm a global variable" console.log(outerVariable); // Output: "I'm an outer variable" console.log(innerVariable); // Output: "I'm an inner variable" } innerFunction(); } outerFunction(); console.log(globalVariable); // Output: "I'm a global variable" console.log(outerVariable); // Output: Uncaught ReferenceError: outerVariable is not defined console.log(blockVariable); // Output: Uncaught ReferenceError: blockVariable is not defined console.log(anotherBlockVariable); // Output: Uncaught ReferenceError: anotherBlockVariable is not defined console.log(innerVariable); // Output: Uncaught ReferenceError: innerVariable is not defined
It is behavior in JS where variable and function declarations are moved to top of their respective scopes, regardless of where they are actually declared in code.
In other words, even if you declare variable or function after you use it in your code, JS will still treat declaration as if it had been made at beginning of current scope. This can sometimes lead to unexpected behavior in your code.
varkeyword are hoisted to top of their respective scopes, but initial value of the variable is set toundefined.console.log(x); // Output: undefined var x = 10;
var function expressionare hoisted, but their values are not set until code is executed.myFunction(); // Output: Uncaught TypeError: myFunction is not a function var myFunction = function() { console.log("Hello, world!"); }
myFunction()still works becausefunction declarationis hoisted to top of current scopemyFunction(); // Output: "I am function declared in code below." function myFunction() { console.log("I am function declared in code below."); }
It is a concept that determines how variable names are resolved at runtime based on their position in the source code during the static phase of code compilation. It is determined by the nesting of functions within other functions or code blocks in the source code, and it remains fixed during the entire runtime of the program.
Lexical scope plays a role in determining the variable scope. Variables declared in a certain scope (function or a code block) have access to the surrounding lexical scope, which allows them to access variables from their parent scopes.\
In other words, lexical scope is determined by the nesting of functions within other functions or code blocks in the source code. When a variable is referenced within a function, JS looks for that variable first within the local scope of the function, and if not found, it looks in the next outer scope until it reaches the global scope.
const globalVar = 'I am global!'; function outerFunction() { const outerVar = 'I am outer!'; function innerFunction() { const innerVar = 'I am inner!'; console.log(globalVar); // accesses from global scope console.log(outerVar); // accesses from outer scope console.log(innerVar); // accesses from local scope } innerFunction(); } outerFunction();
- arithmetic
- addition:
+ - subtraction:
- - multiplication:
* - division:
/ - modulus (remainder of division operation):
% - increment (adds 1 to variable):
++ - decrement (subtracts 1 from variable):
--
let initialValue = 20; let firstIncrement = initialValue++; console.log(firstIncrement); // => 20 console.log(initialValue); // => 21 let firstDecrement = initialValue--; console.log(firstDecrement); // => 21 console.log(initialValue); // => 20
- addition:
- comparison
- equal to:
== - not equal to:
!= - strict equal to (checks both value and data type):
=== - strict not equal to:
!== - greater than:
> - less than:
< - greater than or equal to:
>= - less than or equal to:
<=
- equal to:
- logical
- AND:
&& - OR:
|| - NOT:
!
- AND:
- bitwise
- string
- numeric
- boolean
- object