- Awards Season
- Big Stories
- Pop Culture
- Video Games
MORE FROM ASK.COM
- Skip to main content
- Skip to search
- Skip to select language
- Sign up for free
- English (US)
Logical OR assignment (||=)
The logical OR assignment ( ||= ) operator only evaluates the right operand and assigns to the left if the left operand is falsy .
Logical OR assignment short-circuits , meaning that x ||= y is equivalent to x || (x = y) , except that the expression x is only evaluated once.
No assignment is performed if the left-hand side is not falsy, due to short-circuiting of the logical OR operator. For example, the following does not throw an error, despite x being const :
Neither would the following trigger the setter:
In fact, if x is not falsy, y is not evaluated at all.
Setting default content
If the "lyrics" element is empty, display a default value:
Here the short-circuit is especially beneficial, since the element will not be updated unnecessarily and won't cause unwanted side-effects such as additional parsing or rendering work, or loss of focus, etc.
Note: Pay attention to the value returned by the API you're checking against. If an empty string is returned (a falsy value), ||= must be used, so that "No lyrics." is displayed instead of a blank space. However, if the API returns null or undefined in case of blank content, ??= should be used instead.
- Logical OR ( || )
- Nullish coalescing operator ( ?? )
- Bitwise OR assignment ( |= )
- DSA with JS - Self Paced
- JS A to Z Guide
- JS Operator
- JS Examples
- Free JS Course
- Explore Our Geeks Community
The simple assignment operator is used to assign a value to a variable. The assignment operation evaluates the assigned value. Chaining the assignment operator is possible in order to assign a single value to multiple variables. See the example.
Assignment Operators List: There are so many assignment operators as shown in the table with the description.
Below we have described each operator with an example code:
Addition Assignment : This operator adds the value to the right operand to a variable and assigns the result to the variable. The types of the two operands determine the behavior of the addition assignment operator. Addition or concatenation is possible. In case of concatenation then we use the string as an operand.
Subtraction Assignment: This operator subtracts the value of the right operand from a variable and assigns the result to the variable.
Multiplication Assignment: This operator multiplies a variable by the value of the right operand and assigns the result to the variable.
Division Assignment : This operator divides a variable by the value of the right operand and assigns the result to the variable.
Remainder Assignment : This operator divides a variable by the value of the right operand and assigns the remainder to the variable.
Exponentiation Assignment: This operator raises the value of a variable to the power of the right operand.
Left Shift Assignment: This operator moves the specified amount of bits to the left and assigns the result to the variable.
Right Shift Assignment: This operator moves the specified amount of bits to the right and assigns the result to the variable.
Bitwise AND Assignment : This operator uses the binary representation of both operands, does a bitwise AND operation on them, and assigns the result to the variable.
Bitwise OR Assignment : This operator uses the binary representation of both operands, does a bitwise OR operation on them, and assigns the result to the variable.
Bitwise XOR Assignment: This operator uses the binary representation of both operands, does a bitwise XOR operation on them, and assigns the result to the variable.
Please Login to comment...
- Web Technologies
Please write us at [email protected] to report any issue with the above content
Improve your Coding Skills with Practice
There are also live events, courses curated by job role, and more.
The = operator expects its left-side operand to be an lvalue: a variable or object property (or array element). It expects its right-side operand to be an arbitrary value of any type. The value of an assignment expression is the value of the right-side operand. As a side effect, the = operator assigns the value on the right to the variable or property on the left so that future references to the variable or property evaluate to the value.
Although assignment expressions are usually quite simple, you may sometimes see the value of an assignment expression used as part of a larger expression. For example, you can assign and test a value in the same expression with code like this:
If you do this, be sure you are clear on the difference between the = and == operators! Note that = has very low precedence and parentheses are usually necessary when the value of an assignment is to be used in a larger expression.
The assignment operator has right-to-left associativity, which means that when multiple assignment operators appear in an expression, they are evaluated from right to left. Thus, you can write code like this to assign a single value to multiple variables:
Assignment with Operation
is equivalent to this one:
As you might expect, the += operator works for numbers or strings. For numeric operands, it performs addition and assignment; for string operands, it performs concatenation and assignment.
Similar operators include -= , *= , &= , and so on. Table 4-3 lists them all.
Table 4-3. Assignment operators
In most cases, the expression:
where op is an operator, is equivalent to the expression:
In the first line, the expression a is evaluated once. In the second it is evaluated twice. The two cases will differ only if a includes side effects such as a function call or an increment operator. The following two assignments, for example, are not the same:
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.
Don’t leave empty-handed
Get Mark Richards’s Software Architecture Patterns ebook to better understand how to design components—and how they should interact.
It’s yours, free.
Check it out now on O’Reilly
Dive in for free with a 10-day trial of the O’Reilly learning platform—then explore all the other resources our members count on to build skills and solve problems every day.
11 Variables and assignment
11.1 let, 11.2.1 const and immutability, 11.2.2 const and loops.
- 11.3 Deciding between const and let
- 11.4.1 Shadowing variables
- 11.5 (Advanced)
- 11.6.1 Static phenomenon: scopes of variables
- 11.6.2 Dynamic phenomenon: function calls
11.7.1 globalThis [ES2020]
11.8.1 const and let : temporal dead zone.
- 11.8.2 Function declarations and early activation
- 11.8.3 Class declarations are not activated early
11.8.4 var : hoisting (partial early activation)
- 11.9.1 Bound variables vs. free variables
- 11.9.2 What is a closure?
- 11.9.3 Example: A factory for incrementors
- 11.9.4 Use cases for closures
- let declares mutable variables.
- const declares constants (immutable variables).
Variables declared via let are mutable:
You can also declare and assign at the same time:
Variables declared via const are immutable. You must always initialize immediately:
You can use const with for-of loops, where a fresh binding is created for each iteration:
In plain for loops, you must use let , however:
11.3 Deciding between const and let
I recommend the following rules to decide between const and let :
- const indicates an immutable binding and that a variable never changes its value. Prefer it.
- let indicates that the value of a variable changes. Use it only when you can’t use const .
11.4 The scope of a variable
The scope of a variable is the region of a program where it can be accessed. Consider the following code.
- Scope A is the (direct) scope of x .
- Scopes B and C are inner scopes of scope A.
- Scope A is an outer scope of scope B and scope C.
Each variable is accessible in its direct scope and all scopes nested within that scope.
The variables declared via const and let are called block-scoped because their scopes are always the innermost surrounding blocks.
11.4.1 Shadowing variables
You can’t declare the same variable twice at the same level:
eval() delays parsing (and therefore the SyntaxError ), until the callback of assert.throws() is executed. If we didn’t use it, we’d already get an error when this code is parsed and assert.throws() wouldn’t even be executed.
You can, however, nest a block and use the same variable name x that you used outside the block:
Inside the block, the inner x is the only accessible variable with that name. The inner x is said to shadow the outer x . Once you leave the block, you can access the old value again.
See quiz app .
All remaining sections are advanced.
11.6 Terminology: static vs. dynamic
These two adjectives describe phenomena in programming languages:
- Static means that something is related to source code and can be determined without executing code.
- Dynamic means at runtime.
Let’s look at examples for these two terms.
11.6.1 Static phenomenon: scopes of variables
Variable scopes are a static phenomenon. Consider the following code:
x is statically (or lexically ) scoped . That is, its scope is fixed and doesn’t change at runtime.
Variable scopes form a static tree (via static nesting).
11.6.2 Dynamic phenomenon: function calls
Function calls are a dynamic phenomenon. Consider the following code:
Whether or not the function call in line A happens, can only be decided at runtime.
Function calls form a dynamic tree (via dynamic calls).
11.7 Global variables and the global object
- The outermost scope is the root of the tree.
- The scopes directly contained in that scope are the children of the root.
The root is also called the global scope . In web browsers, the only location where one is directly in that scope is at the top level of a script. The variables of the global scope are called global variables and accessible everywhere. There are two kinds of global variables:
- They can only be created while at the top level of a script, via const , let , and class declarations.
- They are created in the top level of a script, via var and function declarations.
- The global object can be accessed via the global variable globalThis . It can be used to create, read, and delete global object variables.
- Other than that, global object variables work like normal variables.
The following HTML fragment demonstrates globalThis and the two kinds of global variables.
Each ECMAScript module has its own scope. Therefore, variables that exist at the top level of a module are not global. Fig. 5 illustrates how the various scopes are related.
The global variable globalThis is the new standard way of accessing the global object. It got its name from the fact that it has the same value as this in global scope.
For example, in browsers, there is an indirection . That indirection is normally not noticable, but it is there and can be observed.
188.8.131.52 Alternatives to globalThis
Older ways of accessing the global object depend on the platform:
- Global variable window : is the classic way of referring to the global object. But it doesn’t work in Node.js and in Web Workers.
- Global variable self : is available in Web Workers and browsers in general. But it isn’t supported by Node.js.
- Global variable global : is only available in Node.js.
184.108.40.206 Use cases for globalThis
ECMAScript 6 introduced several features that make it easier to avoid the global object – for example:
- const , let , and class declarations don’t create global object properties when used in global scope.
- Each ECMAScript module has its own local scope.
Tutorials on the web occasionally access global variables globVar via window.globVar . But the prefix “ window. ” is not necessary and I recommend to omit it:
Therefore, there are relatively few use cases for globalThis – for example:
11.8 Declarations: scope and activation
These are two key aspects of declarations:
- Scope: Where can a declared entity be seen? This is a static trait.
- Activation: When can I access an entity? This is a dynamic trait. Some entities can be accessed as soon as we enter their scopes. For others, we have to wait until execution reaches their declarations.
Tbl. 1 summarizes how various declarations handle these aspects.
import is described in §27.5 “ECMAScript modules” . The following sections describe the other constructs in more detail.
Some possible approaches are:
- The name is resolved in the scope surrounding the current scope.
- You get undefined .
- There is an error.
Approach 2 was rejected because then x wouldn’t be a constant – it would have different values before and after its declaration.
let uses the same approach 3 as const , so that both work similarly and it’s easy to switch between them.
The time between entering the scope of a variable and executing its declaration is called the temporal dead zone (TDZ) of that variable:
- During this time, the variable is considered to be uninitialized (as if that were a special value it has).
- If you access an uninitialized variable, you get a ReferenceError .
- Once you reach a variable declaration, the variable is set to either the value of the initializer (specified via the assignment symbol) or undefined – if there is no initializer.
The following code illustrates the temporal dead zone:
The next example shows that the temporal dead zone is truly temporal (related to time):
Even though func() is located before the declaration of myVar and uses that variable, we can call func() . But we have to wait until the temporal dead zone of myVar is over.
11.8.2 Function declarations and early activation
In this section, we are using functions – before we had a chance to learn them properly. Hopefully, everything still makes sense. Whenever it doesn’t, please see §25 “Callable values” .
A function declaration is always executed when entering its scope, regardless of where it is located within that scope. That enables you to call a function foo() before it is declared:
The early activation of foo() means that the previous code is equivalent to:
If you declare a function via const or let , then it is not activated early. In the following example, you can only use bar() after its declaration.
220.127.116.11 Calling ahead without early activation
Even if a function g() is not activated early, it can be called by a preceding function f() (in the same scope) if we adhere to the following rule: f() must be invoked after the declaration of g() .
The functions of a module are usually invoked after its complete body is executed. Therefore, in modules, you rarely need to worry about the order of functions.
Lastly, note how early activation automatically keeps the aforementioned rule: when entering a scope, all function declarations are executed first, before any calls are made.
18.104.22.168 A pitfall of early activation
If you rely on early activation to call a function before its declaration, then you need to be careful that it doesn’t access data that isn’t activated early.
The problem goes away if you make the call to funcDecl() after the declaration of MY_STR .
22.214.171.124 The pros and cons of early activation
We have seen that early activation has a pitfall and that you can get most of its benefits without using it. Therefore, it is better to avoid early activation. But I don’t feel strongly about this and, as mentioned before, often use function declarations because I like their syntax.
11.8.3 Class declarations are not activated early
Even though they are similar to function declarations in some ways, class declarations are not activated early:
Why is that? Consider the following class declaration:
The operand of extends is an expression. Therefore, you can do things like this:
Evaluating such an expression must be done at the location where it is mentioned. Anything else would be confusing. That explains why class declarations are not activated early.
var is an older way of declaring variables that predates const and let (which are preferred now). Consider the following var declaration.
This declaration has two parts:
- Declaration var x : The scope of a var -declared variable is the innermost surrounding function and not the innermost surrounding block, as for most other declarations. Such a variable is already active at the beginning of its scope and initialized with undefined .
- Assignment x = 123 : The assignment is always executed in place.
The following code demonstrates the effects of var :
Before we can explore closures, we need to learn about bound variables and free variables.
11.9.1 Bound variables vs. free variables
Per scope, there is a set of variables that are mentioned. Among these variables we distinguish:
- Bound variables are declared within the scope. They are parameters and local variables.
- Free variables are declared externally. They are also called non-local variables .
Consider the following code:
In the body of func() , x and y are bound variables. z is a free variable.
11.9.2 What is a closure?
What is a closure then?
A closure is a function plus a connection to the variables that exist at its “birth place”.
What is the point of keeping this connection? It provides the values for the free variables of the function – for example:
funcFactory returns a closure that is assigned to func . Because func has the connection to the variables at its birth place, it can still access the free variable value when it is called in line A (even though it “escaped” its scope).
11.9.3 Example: A factory for incrementors
The following function returns incrementors (a name that I just made up). An incrementor is a function that internally stores a number. When it is called, it updates that number by adding the argument to it and returns the new value.
We can see that the function created in line A keeps its internal number in the free variable startValue . This time, we don’t just read from the birth scope, we use it to store data that we change and that persists across function calls.
We can create more storage slots in the birth scope, via local variables:
11.9.4 Use cases for closures
What are closures good for?
For starters, they are simply an implementation of static scoping. As such, they provide context data for callbacks.
They can also be used by functions to store state that persists across function calls. createInc() is an example of that.
And they can provide private data for objects (produced via literals or classes). The details of how that works are explained in Exploring ES6 .
An assignment operator ( = ) assigns a value to a variable. The syntax of the assignment operator is as follows:
The following example declares the counter variable and initializes its value to zero:
The following example increases the counter variable by one and assigns the result to the counter variable:
To make the code more concise, you can use the += operator like this:
In this syntax, you don’t have to repeat the counter variable twice in the assignment.
The following table illustrates assignment operators that are shorthand for another operator and the assignment:
If you want to assign a single value to multiple variables, you can chain the assignment operators. For example:
- Use the assignment operator ( = ) to assign a value to a variable.
- Chain the assignment operators if you want to assign a single value to multiple variables.
The Addition Operator + adds numbers:
The Assignment Operator = assigns a value to a variable.
The Assignment Operator ( = ) assigns a value to a variable:
The Addition Operator ( + ) adds numbers:
The Multiplication Operator ( * ) multiplies numbers:
- Arithmetic Operators
- Assignment Operators
- Comparison Operators
- String Operators
- Logical Operators
- Bitwise Operators
- Ternary Operators
- Type Operators
Arithmetic Operators are used to perform arithmetic on numbers:
Arithmetic Operators Example
Arithmetic operators are fully described in the JS Arithmetic chapter.
The Addition Assignment Operator ( += ) adds a value to a variable.
Assignment operators are fully described in the JS Assignment chapter.
Comparison operators are fully described in the JS Comparisons chapter.
All the comparison operators above can also be used on strings:
Note that strings are compared alphabetically:
The + can also be used to add (concatenate) strings:
The += assignment operator can also be used to add (concatenate) strings:
The result of text1 will be:
When used on strings, the + operator is called the concatenation operator.
Adding Strings and Numbers
Adding two numbers, will return the sum, but adding a number and a string will return a string:
The result of x , y , and z will be:
If you add a number and a string, the result will be a string!
Logical operators are fully described in the JS Comparisons chapter.
Type operators are fully described in the JS Type Conversion chapter.
Bit operators work on 32 bits numbers.
Bitwise operators are fully described in the JS Bitwise chapter.
Test Yourself With Exercises
Multiply 10 with 5 , and alert the result.
Start the Exercise
Test Yourself with Exercises!
Exercise 1 » Exercise 2 » Exercise 3 » Exercise 4 » Exercise 5 »
If you want to report an error, or if you want to make a suggestion, do not hesitate to send us an e-mail:
Top references, top examples, get certified.
Free System Design Interview Course
Many candidates are rejected or down-leveled due to poor performance in their System Design Interview. Stand out in System Design Interviews and get hired in 2023 with this popular free course.
The &&= operator
The &&= is pronounced as “Logical AND assignment operator” and is used in between two values.
If the first value is truthy, then the second value is assigned. It is evaluated left to right.
In the first evaluation on line 5, expression1 is falsy. The expression1 value will not change.
In the second evaluation on line 7, expression2 is truthy. The expression3 value will be assigned to expression2 .
The ||= operator
The ||= is pronounced as “Logical OR assignment operator” and is used in between two values.
If the first value is falsy, then the second value is assigned. It is evaluated left to right.
In the first evaluation on line 5, the expression1 is falsy. The expression2 value will be assigned to expression1 .
In the second evaluation on line 7, expression2 is truth. The expression2 value will not change.
The ??= operator
The ??= is pronounced as “Nullish coalescing assignment operator” and is used in between two values.
If the first value is undefined or null , then the second value is assigned. It is evaluated left to right.
In the first evaluation on line 5, expression1 is null . The expression2 value will be assigned to expression1 .
In the second evaluation on line 7, expression2 is neither null nor undefined . The expression2 value will not change.
Learn in-demand tech skills in half the time
Learn to Code
Data Science & ML
GitHub Students Scholarship
Early Access Courses
Try for Free
Become an Author
Become an Affiliate
Earn Referral Credits
Frequently Asked Questions
Terms of Service
Business Terms of Service
Data Processing Agreement
Copyright © 2023 Educative, Inc. All rights reserved.
Require or disallow assignment operator shorthand where possible
Some problems reported by this rule are automatically fixable by the --fix command line option
This rule requires or disallows assignment operator shorthand where possible.
The rule applies to the operators listed in the above table. It does not report the logical assignment operators &&= , ||= , and ??= because their short-circuiting behavior is different from the other assignment operators.
This rule has a single string option:
- "always" (default) requires assignment operator shorthand where possible
- "never" disallows assignment operator shorthand
Examples of incorrect code for this rule with the default "always" option:
Examples of correct code for this rule with the default "always" option:
Examples of incorrect code for this rule with the "never" option:
Examples of correct code for this rule with the "never" option:
When Not To Use It
Use of operator assignment shorthand is a stylistic choice. Leaving this rule turned off would allow developers to choose which style is more readable on a case-by-case basis.
This rule was introduced in ESLint v0.10.0.
- Rule source
- Tests source