Can someone please tell me what this snippet is doing?
Is it setting x to true if y is undefined?
var x = false;
var y = x === true;
The code
var x = false;
var y = x === true;
console.log(y);
is simply checking the condition x === true, like other programming language it will result to either true or false. Since you have var x = false; the condition x === true will result in false as false === true is always false. Now, the result of this condition is being assigned to the new variable y as var y = x === true; so the value for y will be false.
Set x to false
Is x exactly-equal to true?
2.1. If so, then set y to true
2.2. Otherwise, set y to false
There is no invokation of of global.undefined in this fragment.
The first line should be pretty clear, it sets x to false. The second line is a bit more difficult, first, it compares x to true. If x is exactly equal to true, it will set y to true. Since x is false, the comparison will also return false, so y will be set to false.
TL;DR, this is a convoluted way of setting y to false.
=== is a strict comparison operator. The value of variable y will only true if x is boolean and true, y will be false otherwise. Check this snippet out for example:
let a = 1;
console.log(a == true); // print true
let b = 1;
console.log(b === true); // print false, because `b` is a number, not boolean
let c = true;
console.log(c == true); // print true
let d = true;
console.log(d === true); // print true, because `d` is a boolean and its value is `true`
This var y = x === true; statement means: keep the returned value of (x === true) in the y variable. In your case, y will hold false as its value since x is a boolean, but its value is false.
Strict Equality Operator, === has a greater precedence over Assignment Operator, =. Therefore the check for x is done before assigning its value to y.
You can break this down into three statements.
var x = false
var tmp = (x === true)
var y = tmp
Since x is false, y will also get set to false.
Related
I have seen this syntax in node.jsv15.0.1: &&=, ||= and ??=.
But I don't know what it does. Does anyone know?
These are the new logical assignment operators. They're similar to the more familiar operators like *=, +=, etc.
someVar &&= someExpression is roughly equivalent to someVar = someVar && someExpression.
someVar ||= someExpression is roughly equivalent to someVar = someVar || someExpression.
someVar ??= someExpression is roughly equivalent to someVar = someVar ?? someExpression.
I say "roughly" because there's one difference - if the expression on the right-hand side isn't used, possible setters are not invoked. So it's a bit closer to:
someVar &&= someExpression is like
if (!someVar) {
someVar = someExpression;
}
and so on. (The fact that a setter isn't invoked is unlikely to have an effect on the script, but it's not impossible.) This is unlike the other traditional shorthand assignment operators which do unconditionally assign to the variable or property (and thus invoke setters). Here's a snippet to demonstrate:
const obj = {
_prop: 1,
set prop(newVal) {
this._prop = newVal;
},
get prop() {
return this._prop;
}
};
// Setter does not get invoked:
obj.prop ||= 5;
??, if you aren't familiar with it, is the nullish coalescing operator. It will evaluate to the right-hand side if the left-hand side is either null or undefined.
Those are called Logical Assignment Operators and there are three in total:
Logical AND assignment (&&=)
Logical OR assignment (||=)
Logical nullish assignment (??=)
Fundamentally they all do the same: The logical operators &&, ?? and || in front of the = as in x logical-operator= y can be rewritten as x logical-operator (x = y). Their only purpose is to replace more verbose code:
x &&= y does nothing if x is not truthy and changes x's value to y if x is truthy. It is the same as:
if (x) {
x = y
}
x ||= y does nothing if x is truthy and changes x's value to y if x is not truthy. It is the same as:
if (!x) {
x = y
}
x ??= y does nothing if x is not nullish and changes x's value to y if x is nullish. It is the same as:
if (x === null || x === undefined) {
x = y
}
Here are some examples to further your understanding of these:
const y = 'other value'
let def = 'initial' // truthy value
let zero = 0 // not truth value
let undef = undefined // nullish value
def &&= y // def = 'other value'
zero &&= y // zero = 0
undef &&= y // undef = 'undefined'
def ||= y // def = 'initial'
zero ||= y // zero = 'other value'
undef ||= y // undef = 'other value'
def ??= y // def = 'initial'
zero ??= y // zero = 0
undef ??= y // undef = 'other value'
a = a || b is equivalent to a ||= b => if a is true, a return but if a is false b return.
a = a && b is equivalent to a &&= b => if a is true, b return but if a is false a return.
a = a ?? b is equivalent to a ??= b => if a just is null or undefined, b return but if a is true a return.
note: null, undefined, "", 0, NaN are false
examples:
let a = -22
const b = false
a &&= b
console.log(a) // false
let a = 0
const b = 'hello'
a ||= b
console.log(a) // hello
let a = false
let b = true
a ??= b
console.log(a) // false
let a = null
let b = true
a ??= b
console.log(a) // true
If you do not understand, read it again!
I am confuse for these comparison and I don't know how can be happen.
in bottom code when I compare x and y for less than or great than, it return false but when I compare them with equals they return true!
do you know why this happen?
var x = { y: 10 };
var y = { y: 11 };
x < y; // false
x == y; // false
x > y; // false
x <= y; // true
x >= y; // true
now I understand how are x <= y and y <= x resulting in true however x < y and x == y and x > y are all false.
in continue of accepted answer I can say these happen because the spec says for x <= y , it will actually evaluate y < x first, and then negate that result. Since y < x is also false, the result of x <= y is true.
x < y; // false
x > y; // false
When any operand of a relational operator is an object, it is converted to a primitive value. So in this case, both x and y are first converted to primitive values and then compared with each other.
Both x and y will be converted to primitive values by eventually calling .toString() method on each object which will return a string of the form: [object Object] and since both objects will be converted in this string form, x < y and x > y both evaluate to false because both strings, i.e. [object Object] are equal.
x == y; // false
This evaluates to false because when types of both operands of == operator are same, javascript performs strict equality comparison ===, and as both objects are two separate objects in memory, they are not equal.
x <= y; // true
x >= y; // true
These both expressions evaluate to true because the following comparison
"[object Object]" == "[object Object]"
evaluates to true.
How it's work for example;
let x;
console.log(x || 2); // 2
if
let x = 4;
console.log(x || 2); // 4
if
let x = 5;
let y = 7;
console.log( y || x || 2);
it's mean that console.log() write first value that is true ?
What you're seeing isn't related to console.log. It's called short circuiting.
When comparing values with ||, it will always return the first truthy value. If no truthy values are present, it will return the last value being compared.
let a = false || true;
let b = false || null || 'b';
let c = undefined || !a || 10;
let d = undefined || false || null; // no truthy values
console.log(a); // true
console.log(b); // 'b'
console.log(c); // 10
console.log(d); // null
let x = 5;
let y = 7;
console.log( y || x || 2); //return 7
expr1 || expr2 Returns expr1 if it can be converted to true; otherwise, returns expr2. Thus, when used with Boolean values, || returns true if either operand is true.
Documentation: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators
Is there any value for what x === x returns false without NaN?
For example:
> x = 1
1
> x === x
true
> x = {}
{}
> x === x
true
> x = new Date()
Wed Nov 13 2013 15:44:22 GMT+0200 (EET)
> x === x
true
> x = NaN
NaN
> x === x
false
I see that the only value where x === x returns false is when isNaN(x) === true.
Is there another value of x for what x === x returns false? An official reference would be welcome!
The strict comparison between two equal non-NaN values will always be true (SLaks's answer correctly quotes the spec). However, it's possible for the expression x to change its value during the evaluation of the the equality. This can happen with property access when using accessor property descriptors (i.e., property getters):
foo = {};
Object.defineProperty(foo, "bar", {
get: function() {
return Math.random();
}
})
foo.bar === foo.bar; // false
If you do this for the global object window (or global in Node), then you can see the x === x comparison fail for a global-scope variable:
Object.defineProperty(window, "bar", {
get: function() {
return Math.random();
}
})
bar === bar; // false
The spec lists the exact rules for strict equality.
There are no other such cases, unless you count +0 and -0.
The SameValue algorithm (used for validating changes to read-only defined properties) has no such exceptions.
Consider the code snippet below from this AngularJS tutorial:
app.factory('Auth',
function ($firebaseSimpleLogin, FIREBASE_URL, $rootScope) {
var ref = new Firebase(FIREBASE_URL);
var auth = $firebaseSimpleLogin(ref);
var Auth = {
register: function (user) {
return auth.$createUser(user.email, user.password);
},
signedIn: function () {
return auth.user !== null;
},
logout: function () {
auth.$logout();
}
};
$rootScope.signedIn = function () {
return Auth.signedIn();
};
return Auth;
});
I understand the difference between != and !== is the first compares by reference and the second compares by value. Since the comparison here is to null, then why has the developer chosen to use !== instead of !=? Is my understanding correct that both would work here?
== / != operator only compares the value of the variables, not the type
=== / !== operator compares the type and the value of the variables
Some examples:
var varA = 5; // int
var varB = '5'; // string
var varC = 5; // int
if(varA == varB) // true (only value compared)
if(varA === varB) // false: because varB is of type string and varA of type int
if(varA == varC) // true
if(varA === varC) // true: because varA and varC are of the same type and have the same value
I often use "if(x != null)" to check if x is either null or undefined. It's safer than just saying "if(x)" since there are other falsey values besides null and undefined.
Here's an overview table, for your convenience: http://jsfiddle.net/QQcVw/1/
0 "" false null undefined
0 Y Y Y n n
"" Y Y Y n n
false Y Y Y n n
null n n n Y Y
undefined n n n Y Y
As you can see, == considers equal three empty "values" (0, "" and false) and two "non-values" (null and undefined). See javascript standard for the exact algorithm.
In most cases, it's a good idea to avoid == and always stick to ===.