Welcome to Software Development on Codidact!
Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.
Post History
Assignment (=) = is the assignment operator: it assigns a value to "something". One important detail is that an assignment expression not only assigns a value, but it also returns it. This allows...
Answer
#2: Post edited
- # Assignment (`=`)
- `=` is the [assignment operator](https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-assignment-operators): it assigns a value to "something".
- One important detail is that an assignment expression not only assigns a value, but it also returns it. This allows chaining, such as:
- ```javascript
- x = y = z = 1; // all variables will be assigned the value 1
- ```
- According to the [operator precedence rules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#precedence_and_associativity), assignment is right-associative, so the code above is actually equivalent to:
- ```javascript
- x = (y = (z = 1));
- ```
- As the expression also returns the assigned value, the code above is evaluated as:
- - `z` is assigned the value `1`
- - the expression `z = 1` returns the value `1`
- - `y` is assigned the value returned by `(z = 1)` (which is also `1`)
- - the expression `(y = (z = 1))` returns the value `1`
- - `x` is assigned the value returned by `(y = (z = 1))` (which is also `1`)
- This allows even more complicated things, such as:
- ```javascript
- x = (y = (z = 1) + 1) + y;
- ```
- In this case, the code executes as follows:
- - `z` is assigned the value `1`
- - the expression `z = 1` returns the value `1`
- - `y` is assigned the value returned by `(z = 1) + 1` (which is `2`)
- - the expression `(y = (z = 1) + 1)` returns the value `2`
- - `x` is assigned the value returned by `(y = (z = 1) + 1) + y` (which is `4`)
- Although I'd never use expressions like this in production code. But the fact that an assignment returns a value can be useful in cases like this:
- ```javascript
- while ((x = somefunc()) >= 0) {
- // do something with x
- }
- ```
- Assuming that `somefunc` returns some number, and I want to loop until this number is negative (and also do something with it inside the loop). Of course I could rewrite the same code as:
- ```javascript
- while (true) {
- x = somefunc();
if (x <= 0)- break;
- // do something with x
- }
- ```
- But I think the former is more straighforward.
- ---
- Another caveat regards to variable declaration. See this code:
- ```java
- const x = y = 1;
- y = 2; // ok
- x = 2; // ERROR
- ```
- A `const` variable can't be changed through assignment, so trying to assign `x = 2` causes an error. But `y = 2` is perfectly fine, because `const` applies only to `x`. Remember that `=` is right-associative, so the first line above corresponds to:
- ```javascript
- const x = (y = 1);
- ```
- If I want both `x` and `y` to be constants, I'd have to do this:
- ```javascript
- const x = 1, y = 1;
- ```
- ---
- And last but not least, the left side of `=` is not restricted to single variable names:
- ```javascript
- // if x is an array, assign value to specific index
- x[2] = value;
- // assign value to a property of "x" object
- x.property = value;
- // if value is an array, x and y will be its first and second elements
- [x, y] = value;
- // destructuring assignment, get "name" and "age" properties of object and assigning them to the respective variables
- var { name, age } = obj;
- ```
- ---
- # Equality Operators: `==` vs `===`
- According to MDN, `==` is the [equality operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Equality) and `===` is the [strict equality operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Strict_equality), but the ECMAScript language specification just calls them ["Equality Operators"](https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-equality-operators). You can call them "loose" and "strict" equality, though, as these terms usage has become common and well known.
- Both always return a boolean value (either `true` or `false`). The only difference, according to the [evaluation rules](https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-equality-operators-runtime-semantics-evaluation), is the algorithm used to determine equality.
- ### `==` or "loose equality"
- The `==` operator uses the [`IsLooselyEqual` operation](https://tc39.es/ecma262/multipage/abstract-operations.html#sec-islooselyequal), which makes some type coercions when the operands are of different types. The rules are somewhat complicated (if you compare a number and a string, the string will be converted to a number using the [rules defined in the spec](https://tc39.es/ecma262/multipage/abstract-operations.html#sec-tonumber), but comparing a number and an object will make the object to be [converted to a primitive](https://tc39.es/ecma262/multipage/abstract-operations.html#sec-toprimitive), etc).
- This can cause some strange and unexpected behaviour in many cases, such as `0 == []`, `"1" == [1]` and `"" == [[[]]]`, all of them resulting in `true`.
- Although chaining this operator produces valid code (aka "it runs without compile-errors"), it doesn't work the way you'd expect. Example:
- ```javascript
- x = y = z = 0; // assign zero to all variables
- console.log(x == y == z); // false
- ```
- According to [this table](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#table), both `==` and `===` are evaluated left-to-right, which means that the expression `x == y == z` is equivalent to:
- ```javascript
- (x == y) == z
- ```
- Hence, `x == y` evaluates to `true` (as both `x` and `y` are zero), and then `true == z` evaluates to `false`. To test if the three variables are equal, you should do `x == y && y == z` (or `x === y && y === z`).
- But all these type coercion mess applies only when the two operands are of different types. When they are of the same type, both `==` and `===` behave the same way. In the [specification of `IsLooselyEqual` operation](https://tc39.es/ecma262/multipage/abstract-operations.html#sec-islooselyequal), the first step is:
- 1. If `Type(x)` is the same as `Type(y)`, then
- - Return `IsStrictlyEqual(x, y)`.
- And [according to the spec](https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-equality-operators-runtime-semantics-evaluation), the `IsStrictlyEqual` operation is the same one used by the `===` operator.
- ### `===` or "strict equality"
- As mentioned above, the `===` operator uses the [`IsStrictlyEqual` operation](https://tc39.es/ecma262/multipage/abstract-operations.html#sec-isstrictlyequal), which in turn does the following:
- - if the operands are of type `Number` or `BigInt`, it calls the respective `equal` operation ([this one](https://tc39.es/ecma262/multipage/ecmascript-data-types-and-values.html#sec-numeric-types-number-equal) for `Number` or [this one](https://tc39.es/ecma262/multipage/ecmascript-data-types-and-values.html#sec-numeric-types-bigint-equal) for `BigInt`).
- - in any other case, it uses the [`SameValueNonNumeric` operation](https://tc39.es/ecma262/multipage/abstract-operations.html#sec-samevaluenonnumeric), which defines specific rules for each type
- The difference from `==` is that `===` doesn't do any type coercion: if the operands are of different types, it returns `false` (that's the first thing it checks, BTW).
- But there's one caveat: the "same type" definition is a little bit tricky when objects are involved. Ex:
- ```javascript
- x = [1, 2];
- y = [1, 2];
- z = x;
- console.log(typeof x, typeof y, typeof z); // "object" "object" "object"
- console.log(x === y); // false (although they have the same type)
- console.log(x === z); // true (they reference the same object)
- ```
- The assignment to `y` actually creates another array (hence, it's a different object, although it has the same values of `x`). And when the operands type is neither `Number`, `BigInt`, `Undefined`, `Null`, `String`, `Boolean` nor `Symbol`, the `SameValueNonNumeric` operation only returns `true` if both operands are the same object.
- ---
- The differences between `==` and `===`, and their somewhat complicated rules, might lead to lots of corner cases, such as `null == undefined` being `true` while `null === undefined` is `false`, and many more (some already mentioned in the other answers).
- [Here](https://dorey.github.io/JavaScript-Equality-Table/) you can find some interesting tables with lots of those cases. I'm reproducing some below.
- For the `==` operator:
- ![loose equality](https://software.codidact.com/uploads/pfvqRUNC8DavwLcxmZVNP8Jg)
- And for the `===` operator:
- ![strict equality](https://software.codidact.com/uploads/rmwfZwNDjWmwC7cffTMUWVaL)
- # Assignment (`=`)
- `=` is the [assignment operator](https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-assignment-operators): it assigns a value to "something".
- One important detail is that an assignment expression not only assigns a value, but it also returns it. This allows chaining, such as:
- ```javascript
- x = y = z = 1; // all variables will be assigned the value 1
- ```
- According to the [operator precedence rules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#precedence_and_associativity), assignment is right-associative, so the code above is actually equivalent to:
- ```javascript
- x = (y = (z = 1));
- ```
- As the expression also returns the assigned value, the code above is evaluated as:
- - `z` is assigned the value `1`
- - the expression `z = 1` returns the value `1`
- - `y` is assigned the value returned by `(z = 1)` (which is also `1`)
- - the expression `(y = (z = 1))` returns the value `1`
- - `x` is assigned the value returned by `(y = (z = 1))` (which is also `1`)
- This allows even more complicated things, such as:
- ```javascript
- x = (y = (z = 1) + 1) + y;
- ```
- In this case, the code executes as follows:
- - `z` is assigned the value `1`
- - the expression `z = 1` returns the value `1`
- - `y` is assigned the value returned by `(z = 1) + 1` (which is `2`)
- - the expression `(y = (z = 1) + 1)` returns the value `2`
- - `x` is assigned the value returned by `(y = (z = 1) + 1) + y` (which is `4`)
- Although I'd never use expressions like this in production code. But the fact that an assignment returns a value can be useful in cases like this:
- ```javascript
- while ((x = somefunc()) >= 0) {
- // do something with x
- }
- ```
- Assuming that `somefunc` returns some number, and I want to loop until this number is negative (and also do something with it inside the loop). Of course I could rewrite the same code as:
- ```javascript
- while (true) {
- x = somefunc();
- if (x < 0)
- break;
- // do something with x
- }
- ```
- But I think the former is more straighforward.
- ---
- Another caveat regards to variable declaration. See this code:
- ```java
- const x = y = 1;
- y = 2; // ok
- x = 2; // ERROR
- ```
- A `const` variable can't be changed through assignment, so trying to assign `x = 2` causes an error. But `y = 2` is perfectly fine, because `const` applies only to `x`. Remember that `=` is right-associative, so the first line above corresponds to:
- ```javascript
- const x = (y = 1);
- ```
- If I want both `x` and `y` to be constants, I'd have to do this:
- ```javascript
- const x = 1, y = 1;
- ```
- ---
- And last but not least, the left side of `=` is not restricted to single variable names:
- ```javascript
- // if x is an array, assign value to specific index
- x[2] = value;
- // assign value to a property of "x" object
- x.property = value;
- // if value is an array, x and y will be its first and second elements
- [x, y] = value;
- // destructuring assignment, get "name" and "age" properties of object and assigning them to the respective variables
- var { name, age } = obj;
- ```
- ---
- # Equality Operators: `==` vs `===`
- According to MDN, `==` is the [equality operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Equality) and `===` is the [strict equality operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Strict_equality), but the ECMAScript language specification just calls them ["Equality Operators"](https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-equality-operators). You can call them "loose" and "strict" equality, though, as these terms usage has become common and well known.
- Both always return a boolean value (either `true` or `false`). The only difference, according to the [evaluation rules](https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-equality-operators-runtime-semantics-evaluation), is the algorithm used to determine equality.
- ### `==` or "loose equality"
- The `==` operator uses the [`IsLooselyEqual` operation](https://tc39.es/ecma262/multipage/abstract-operations.html#sec-islooselyequal), which makes some type coercions when the operands are of different types. The rules are somewhat complicated (if you compare a number and a string, the string will be converted to a number using the [rules defined in the spec](https://tc39.es/ecma262/multipage/abstract-operations.html#sec-tonumber), but comparing a number and an object will make the object to be [converted to a primitive](https://tc39.es/ecma262/multipage/abstract-operations.html#sec-toprimitive), etc).
- This can cause some strange and unexpected behaviour in many cases, such as `0 == []`, `"1" == [1]` and `"" == [[[]]]`, all of them resulting in `true`.
- Although chaining this operator produces valid code (aka "it runs without compile-errors"), it doesn't work the way you'd expect. Example:
- ```javascript
- x = y = z = 0; // assign zero to all variables
- console.log(x == y == z); // false
- ```
- According to [this table](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#table), both `==` and `===` are evaluated left-to-right, which means that the expression `x == y == z` is equivalent to:
- ```javascript
- (x == y) == z
- ```
- Hence, `x == y` evaluates to `true` (as both `x` and `y` are zero), and then `true == z` evaluates to `false`. To test if the three variables are equal, you should do `x == y && y == z` (or `x === y && y === z`).
- But all these type coercion mess applies only when the two operands are of different types. When they are of the same type, both `==` and `===` behave the same way. In the [specification of `IsLooselyEqual` operation](https://tc39.es/ecma262/multipage/abstract-operations.html#sec-islooselyequal), the first step is:
- 1. If `Type(x)` is the same as `Type(y)`, then
- - Return `IsStrictlyEqual(x, y)`.
- And [according to the spec](https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-equality-operators-runtime-semantics-evaluation), the `IsStrictlyEqual` operation is the same one used by the `===` operator.
- ### `===` or "strict equality"
- As mentioned above, the `===` operator uses the [`IsStrictlyEqual` operation](https://tc39.es/ecma262/multipage/abstract-operations.html#sec-isstrictlyequal), which in turn does the following:
- - if the operands are of type `Number` or `BigInt`, it calls the respective `equal` operation ([this one](https://tc39.es/ecma262/multipage/ecmascript-data-types-and-values.html#sec-numeric-types-number-equal) for `Number` or [this one](https://tc39.es/ecma262/multipage/ecmascript-data-types-and-values.html#sec-numeric-types-bigint-equal) for `BigInt`).
- - in any other case, it uses the [`SameValueNonNumeric` operation](https://tc39.es/ecma262/multipage/abstract-operations.html#sec-samevaluenonnumeric), which defines specific rules for each type
- The difference from `==` is that `===` doesn't do any type coercion: if the operands are of different types, it returns `false` (that's the first thing it checks, BTW).
- But there's one caveat: the "same type" definition is a little bit tricky when objects are involved. Ex:
- ```javascript
- x = [1, 2];
- y = [1, 2];
- z = x;
- console.log(typeof x, typeof y, typeof z); // "object" "object" "object"
- console.log(x === y); // false (although they have the same type)
- console.log(x === z); // true (they reference the same object)
- ```
- The assignment to `y` actually creates another array (hence, it's a different object, although it has the same values of `x`). And when the operands type is neither `Number`, `BigInt`, `Undefined`, `Null`, `String`, `Boolean` nor `Symbol`, the `SameValueNonNumeric` operation only returns `true` if both operands are the same object.
- ---
- The differences between `==` and `===`, and their somewhat complicated rules, might lead to lots of corner cases, such as `null == undefined` being `true` while `null === undefined` is `false`, and many more (some already mentioned in the other answers).
- [Here](https://dorey.github.io/JavaScript-Equality-Table/) you can find some interesting tables with lots of those cases. I'm reproducing some below.
- For the `==` operator:
- ![loose equality](https://software.codidact.com/uploads/pfvqRUNC8DavwLcxmZVNP8Jg)
- And for the `===` operator:
- ![strict equality](https://software.codidact.com/uploads/rmwfZwNDjWmwC7cffTMUWVaL)
#1: Initial revision
# Assignment (`=`) `=` is the [assignment operator](https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-assignment-operators): it assigns a value to "something". One important detail is that an assignment expression not only assigns a value, but it also returns it. This allows chaining, such as: ```javascript x = y = z = 1; // all variables will be assigned the value 1 ``` According to the [operator precedence rules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#precedence_and_associativity), assignment is right-associative, so the code above is actually equivalent to: ```javascript x = (y = (z = 1)); ``` As the expression also returns the assigned value, the code above is evaluated as: - `z` is assigned the value `1` - the expression `z = 1` returns the value `1` - `y` is assigned the value returned by `(z = 1)` (which is also `1`) - the expression `(y = (z = 1))` returns the value `1` - `x` is assigned the value returned by `(y = (z = 1))` (which is also `1`) This allows even more complicated things, such as: ```javascript x = (y = (z = 1) + 1) + y; ``` In this case, the code executes as follows: - `z` is assigned the value `1` - the expression `z = 1` returns the value `1` - `y` is assigned the value returned by `(z = 1) + 1` (which is `2`) - the expression `(y = (z = 1) + 1)` returns the value `2` - `x` is assigned the value returned by `(y = (z = 1) + 1) + y` (which is `4`) Although I'd never use expressions like this in production code. But the fact that an assignment returns a value can be useful in cases like this: ```javascript while ((x = somefunc()) >= 0) { // do something with x } ``` Assuming that `somefunc` returns some number, and I want to loop until this number is negative (and also do something with it inside the loop). Of course I could rewrite the same code as: ```javascript while (true) { x = somefunc(); if (x <= 0) break; // do something with x } ``` But I think the former is more straighforward. --- Another caveat regards to variable declaration. See this code: ```java const x = y = 1; y = 2; // ok x = 2; // ERROR ``` A `const` variable can't be changed through assignment, so trying to assign `x = 2` causes an error. But `y = 2` is perfectly fine, because `const` applies only to `x`. Remember that `=` is right-associative, so the first line above corresponds to: ```javascript const x = (y = 1); ``` If I want both `x` and `y` to be constants, I'd have to do this: ```javascript const x = 1, y = 1; ``` --- And last but not least, the left side of `=` is not restricted to single variable names: ```javascript // if x is an array, assign value to specific index x[2] = value; // assign value to a property of "x" object x.property = value; // if value is an array, x and y will be its first and second elements [x, y] = value; // destructuring assignment, get "name" and "age" properties of object and assigning them to the respective variables var { name, age } = obj; ``` --- # Equality Operators: `==` vs `===` According to MDN, `==` is the [equality operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Equality) and `===` is the [strict equality operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Strict_equality), but the ECMAScript language specification just calls them ["Equality Operators"](https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-equality-operators). You can call them "loose" and "strict" equality, though, as these terms usage has become common and well known. Both always return a boolean value (either `true` or `false`). The only difference, according to the [evaluation rules](https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-equality-operators-runtime-semantics-evaluation), is the algorithm used to determine equality. ### `==` or "loose equality" The `==` operator uses the [`IsLooselyEqual` operation](https://tc39.es/ecma262/multipage/abstract-operations.html#sec-islooselyequal), which makes some type coercions when the operands are of different types. The rules are somewhat complicated (if you compare a number and a string, the string will be converted to a number using the [rules defined in the spec](https://tc39.es/ecma262/multipage/abstract-operations.html#sec-tonumber), but comparing a number and an object will make the object to be [converted to a primitive](https://tc39.es/ecma262/multipage/abstract-operations.html#sec-toprimitive), etc). This can cause some strange and unexpected behaviour in many cases, such as `0 == []`, `"1" == [1]` and `"" == [[[]]]`, all of them resulting in `true`. Although chaining this operator produces valid code (aka "it runs without compile-errors"), it doesn't work the way you'd expect. Example: ```javascript x = y = z = 0; // assign zero to all variables console.log(x == y == z); // false ``` According to [this table](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#table), both `==` and `===` are evaluated left-to-right, which means that the expression `x == y == z` is equivalent to: ```javascript (x == y) == z ``` Hence, `x == y` evaluates to `true` (as both `x` and `y` are zero), and then `true == z` evaluates to `false`. To test if the three variables are equal, you should do `x == y && y == z` (or `x === y && y === z`). But all these type coercion mess applies only when the two operands are of different types. When they are of the same type, both `==` and `===` behave the same way. In the [specification of `IsLooselyEqual` operation](https://tc39.es/ecma262/multipage/abstract-operations.html#sec-islooselyequal), the first step is: 1. If `Type(x)` is the same as `Type(y)`, then - Return `IsStrictlyEqual(x, y)`. And [according to the spec](https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-equality-operators-runtime-semantics-evaluation), the `IsStrictlyEqual` operation is the same one used by the `===` operator. ### `===` or "strict equality" As mentioned above, the `===` operator uses the [`IsStrictlyEqual` operation](https://tc39.es/ecma262/multipage/abstract-operations.html#sec-isstrictlyequal), which in turn does the following: - if the operands are of type `Number` or `BigInt`, it calls the respective `equal` operation ([this one](https://tc39.es/ecma262/multipage/ecmascript-data-types-and-values.html#sec-numeric-types-number-equal) for `Number` or [this one](https://tc39.es/ecma262/multipage/ecmascript-data-types-and-values.html#sec-numeric-types-bigint-equal) for `BigInt`). - in any other case, it uses the [`SameValueNonNumeric` operation](https://tc39.es/ecma262/multipage/abstract-operations.html#sec-samevaluenonnumeric), which defines specific rules for each type The difference from `==` is that `===` doesn't do any type coercion: if the operands are of different types, it returns `false` (that's the first thing it checks, BTW). But there's one caveat: the "same type" definition is a little bit tricky when objects are involved. Ex: ```javascript x = [1, 2]; y = [1, 2]; z = x; console.log(typeof x, typeof y, typeof z); // "object" "object" "object" console.log(x === y); // false (although they have the same type) console.log(x === z); // true (they reference the same object) ``` The assignment to `y` actually creates another array (hence, it's a different object, although it has the same values of `x`). And when the operands type is neither `Number`, `BigInt`, `Undefined`, `Null`, `String`, `Boolean` nor `Symbol`, the `SameValueNonNumeric` operation only returns `true` if both operands are the same object. --- The differences between `==` and `===`, and their somewhat complicated rules, might lead to lots of corner cases, such as `null == undefined` being `true` while `null === undefined` is `false`, and many more (some already mentioned in the other answers). [Here](https://dorey.github.io/JavaScript-Equality-Table/) you can find some interesting tables with lots of those cases. I'm reproducing some below. For the `==` operator: ![loose equality](https://software.codidact.com/uploads/pfvqRUNC8DavwLcxmZVNP8Jg) And for the `===` operator: ![strict equality](https://software.codidact.com/uploads/rmwfZwNDjWmwC7cffTMUWVaL)