How Does: "(a = b) != c" work in Javascript? - javascript

I was looking through jQuery code $.extend()
I found this:
if ( (options = arguments[ i ]) != null ) {
// Extend the base object
I was wondering what would happen if we move options = arguments[i] out of parenthesis?

a = b assigns b to a and returns b. Thus, (a = b) != c will assign b to a and then check b != c. The parentheses are because otherwise, != will be evaluated before = due to the operator precedence (comparison is evaluated before assignment - source)

a = b!= c
will work like,
a = (b != c)
since = operator has least precedence in all the operators.
e.g.
b = 5
c = 10
a = b != c
>>> false
>>> a will have false value here
Here is the precedence chart and demo
In case of (options = arguments[ i ]) != null, options will be assigned a value of argument[ i ] and then compared with null.

Assignment has less precedence than equality which means
arguments[i] != null
would be processed before
options = arguments[i]
Given a different result than what is desired.
To understand it a little better check here and read about operator precedence

Related

Opposite of nullish coalescing operator

Nullish coalescing operator allows assigning a variable if it's not null or undefined, or an expression otherwise.
a = b ?? other
It is an improvement over previously used || because || will also assign other if b is empty string or other falsy, but not nullish value.
However, sometimes, we also use && for value assignment, for example
a = b && func(b)
where we only want to do func on b if it's not nullish, otherwise assign the nullish b.
Of course, && checks for falsiness, not nullishness. Is there a nullish version of &&?
To my knowledge, there is no such operator and also no proposal to add one. Instead you can rely on the standard way to check for nullish values: b == null
a = b == null ? b : func(b)
This will not answer the question since it was already answered by #str, I'm just posting this here because I don't have enough rep to comment on #Dalou's answer and don't want people to trip on that answer.
a = (b ?? false) && other
Is not the opposite of ??, since a will take the value of b if b is a falsy value other than undefined/null, like '' or 0 for example.
The opposite of ?? should set a to the value of other even if b is '' or 0.
ANSWER:
let a = 9;
if( a!==null || a!==undefined ){ /* actions */ };
if( (a??null) !== null ){ /* actions */ }
PROPOSAL:
const oo = console.log;
let a; // undefined, null
// Syntax proposal: !?
a !? oo('NOT Nullish coalescing operator');
// Logical NOT Nullish assignment:
let a = 7;
a !?= 5;
oo(a); // 5
let b, c = null;
b !?= 3;
oo(b); // undefined
c !?= 8;
oo(c); // null
I don't like it but here's my solution:
output = typeof input === 'boolean' && "other"
Truth table:
input -> output
--------------------
null -> false
undefined -> false
true -> "other"
false -> "other"

in Javascript, why would you write 'b || (b = a);'?

Digging through the glMatrix-0.9.5.min.js source used in my webGL project and I came across several lines of code like this...
vec3.negate = function (a, b)
{
b || (b = a); // <-- What exactly does this line do?
b[0] = -a[0];
b[1] = -a[1];
b[2] = -a[2];
return b;
};
Not sure what that code is doing or even if it's a bug considering it's a third-party file, but I also know I'm not completely up to speed about JavaScript as a language. (For instance, I just learned about protocols because of this. Odd/interesting concept.)
So is that valid, and if so, what exactly is it doing?
My guess is it's shorthand for the following, saying 'If 'b' isn't set, set it to a'
if(!b)
{
b = a;
}
which can also just be written
if(!b) b = a;
which I'd argue is much more clear. But again, I'm guessing as to what that actually means/does. Could be wrong.
Follow-up:
Are these two if-conditions equal?
if(!b){ ... }
if(b == undefined){ ... }
I'm wondering if there's a complication between 'undefined' and a defined value that's 'null'
a better way to write that would be
b = b || a;
That means:
b = b ? b : a; //or
b = b || a;
This is shorthand for
if (!b) { b = a }
Lets break it down:
To the left of the || it is asserting on the truthiness of b http://james.padolsey.com/javascript/truthy-falsey/
If b is truthy, then the part to the right of the || will not be evaluated. If b is falsey, then b will get assigned the value/reference of a.
It's basically setting the value of b to a if b is undefined via the || operator which can be used as a null-coalescing operator in Javascript.
You could think of it in terms of an if-statement as follows :
if(b == undefined){
b = a;
}
A Matter of Preference
It's ultimately a matter of preference with regards to what makes the most sense, but any of the approaches that you'll find in this discussion are likely valid options :
// Explicitly using undefined in the comparison
if(b == undefined) { b = a }
// Using an if-statement (with a not)
if(!b){ b = a }
// Using a ternary operator
b = b ? || a
Regarding Your Follow-up
Follow-up: Are these two if-conditions equal?
if(!b){ ... }
if(b == undefined){ ... }
I'm wondering if there's a complication
between 'undefined' and a defined value that's 'null'
Yes, there can be differences as seen with an empty string, which would have the following results :
var b = '';
!b // true
b == undefined // false
Differentiating null and undefined values can be tricky and since it's a bit of out the scope of this question, you might consider checking out this related discussion on the topic, which commonly recommends the use of if(b == null) { b = a; } as opposed to checks against undefined.

Shorthand way to check for function parameters

In my code, I have a function that creates a new map given a few parameters. I want to make it so that if no parameters are passed, some default values will be used.
Why won't this work:
function create(a,b,c) {
return new Map(a,b,c || 10,1,10); // create new map using a b c as parameters
// or 10, 1, 10 if none entered.
}
create();
Assume that there is a constructor function 'Map' that would accept and process these parameters.
What can i do besides having an if/else type check?
The shortest way i know under some limitations is to use
<var> = <var> || <defaultvalue>;
So
Return new Map((a = a || 10), (b = b || 1), (c = c || 10));
However this way its hardly readable and you might want to consider moving the assignments before the constructor.
The limitation however is that all falsy values lead to the default being assigned which might be a problem for some numeric values.
You can do it this way:
function create(a, b, c) {
a = typeof a !== 'undefined' ? a : 10;
b = typeof b !== 'undefined' ? b : 1;
c = typeof c !== 'undefined' ? c : 10;
return new Map(a, b, c);
}
Javascript does not offer default function value parametization.

TypeScript and ExactEqual

How to check in the most simple way if two objects are equal? I noticed that there's no method ExactEqual()-like, so I wonder if I should do it manually or not.
Thanks for any help!
There is no such method. Take a look at this jqfaq.com link where it was discussed and given the best way to check. This will suitable for both typescript and javascript. Hope, that will help you!.
To quote the most important part of that answer:
//“===” means that they are identical.
//“==” means that they are equal in value.
//( == )
//Each JavaScript value is of a specific “type” (Numbers, strings, Booleans, functions, and objects). So if you try to compare a string with a number, the browser will try to convert the string into a number before doing the comparison.
//So the following will return true.
55 == “55″ //true
0 == false //true
1 == true //true
//(===)
//The === operator will not do the conversion, if two values are not the same type it will return false. In other words, this returns true only if the operands are strictly equal in value or if they are identical objects.
55 === “55″ //false
0 === false //false
1 === true //false
var a = [1, 2, 3];
var b = [1, 2, 3];
var c = a;
var is_ab_eql = (a === b); // false (Here a and b are the same type,and also have the same value)
var is_ac_eql = (a === c); // true.
//Value types (numbers):
//a === b returns true if a and b have the same value and are of the same type.
//Reference types:
//a === b returns true if a and b reference the exact same object.
//Strings:
//a === b returns true if a and b are both strings and contain the exact same characters.
var a = “ab” + “c”;
var b = “abc”;
a === b //true
a == b //true
//in thiss case the above condition will fail
var a = new String(“abc”);
var b = “abc”;
a === b //false
a == b// true
//… since a and b are not a same type.
typeof “abc”; // ‘string’
typeof new String(“abc”)); // ‘object

What does "options = options || {}" mean in Javascript? [duplicate]

This question already has answers here:
What does the construct x = x || y mean?
(12 answers)
Closed 7 years ago.
I came over a snippet of code the other day that I got curious about, but I'm not really sure what it actually does;
options = options || {};
My thought so far; sets variable options to value options if exists, if not, set to empty object.
Yes/no?
This is useful to setting default values to function arguments, e.g.:
function test (options) {
options = options || {};
}
If you call test without arguments, options will be initialized with an empty object.
The Logical OR || operator will return its second operand if the first one is falsy.
Falsy values are: 0, null, undefined, the empty string (""), NaN, and of course false.
ES6 UPDATE: Now, we have real default parameter values in the language since ES6.
function test (options = {}) {
//...
}
If you call the function with no arguments, or if it's called explicitly with the value undefined, the options argument will take the default value. Unlike the || operator example, other falsy values will not cause the use of the default value.
It's the default-pattern..
What you have in your snippet is the most common way to implement the default-pattern, it will return the value of the first operand that yields a true value when converted to boolean.
var some_data = undefined;
var some_obj_1 = undefined;
var some_obj_2 = {foo: 123};
var str = some_data || "default";
var obj = some_obj1 || some_obj2 || {};
/* str == "default", obj == {foo: 123} */
the above is basically equivalent to doing the following more verbose alternative
var str = undefined;
var obj = undefined;
if (some_data) str = some_data;
else str = "default";
if (some_obj1) obj = some_obj1;
else if (some_obj2) obj = some_obj2;
else obj = {};
examples of values yield by the logical OR operator:
1 || 3 -> 1
0 || 3 -> 3
undefined || 3 -> 3
NaN || 3 -> 3
"" || "default" -> "default"
undefined || undefined -> undefined
false || true -> true
true || false -> true
null || "test" -> "test"
undefined || {} -> {}
{} || true -> {}
null || false || {} -> {}
0 || "!!" || 9 -> "!!"
As you can see, if no match is found the value of the last operand is yield.
When is this useful?
There are several cases, though the most popular one is to set the default value of function arguments, as in the below:
function do_something (some_value) {
some_value = some_value || "hello world";
console.log ("saying: " + some_value);
}
...
do_something ("how ya doin'?");
do_something ();
saying: how ya doin'?
saying: hello world
Notes
This is notably one of the differences that javascript have compared to many other popular programming languages.
The operator || doesn't implicitly yield a boolean value but it keeps the operand types and yield the first one that will evaluate to true in a boolean expression.
Many programmers coming from languages where this isn't the case (C, C++, PHP, Python, etc, etc) find this rather confusing at first, and of course there is always the opposite; people coming from javascript (perl, etc) wonders why this feature isn't implemented elsewhere.
Yes. The sample is equivalent to this:
if (options) {
options = options;
} else {
options = {};
}
The OR operator (||) will short-circuit and return the first truthy value.
Yes, that's exactly what it does.
Found another variation of this:
options || (options = {});
Seems to do the same trick.

Categories

Resources