Just read on Javascript book by David Flanagan this case:
(a = b) == 0
But I can't see the use of this. Could be like this?
var b = 0;
var a = b;
if (a == 0) ...
Thanks
Your interpretation is correct. The assignment returns the assigned value.
It just assigns b to a. If b (and consequently a) is 0, the condition is true.
It's evaluated in this order:
(a = b) == 0
-------
^ assign the value of b to a
------------
Check if the value of a equals 0
Pretty much it's the same with:
a = b;
if (a == 0) {
// do something
}
It's just a shorter version. Don't forget to declare the variables, otherwise they will be appended to the global namespace.
This is the short form. Means:
Assign b to a
Then compare the value.
(a = b) assigns b to a and is furthermore an expression with the new value of a.
So (a = b) == 0 is an expression that assigns b to a and is evaluates its relational equality to 0.
In C and C++ you'll often see it written as if (!(a = b)). Some folk find such a form obfuscating as it's a stone's-throw away from the considerably different if(!(a == b)).
Related
So, I'm working on a game, and I want it so that if any of the variables are "NaN" or undefined, variableThatTriggeredThis will be set to 0.
I didn't try anything so far, I have no ideas how I can fix it.
if(example == NaN || foo == NaN || bar == NaN) {
variableThatTriggeredThis = 0;
}
I also wanted to ask if there's a way to select every variable in the code, or for example multiple variables, just like var(one, two) == "100".
You can check variables directly. NaN or undefined are valued as false.
Then use Logical OR ||
expr1 || expr2 If expr1 can be converted to true, returns expr1; else, returns expr2
Example:
example = example || 0 ;
foo = foo || 0 ;
bar = bar || 0 ;
There are several ways you could write this. Here's one option using array destructuring:
let a = 10;
let b = 0/0; // NaN
let c; // undefined
const undefinedOrNaNCheck = value => (value === undefined || Number.isNaN(value)) ? 0 : value;
[a, b, c] = [a, b, c].map(undefinedOrNaNCheck);
console.log([a, b, c]);
To coerce a variable into a number (defaulting to 0):
example = isNaN(example) ? 0 : example * 1;
To process several variables, one approach is to create a parent object:
const scores = {};
scores.example = 10;
scores.foo = undefined;
scores.bar = 'not a number';
... allowing iteration like this:
Object.keys(scores).forEach(function(key) {
scores[key] = isNaN(scores[key]) ? 0 : scores[key] * 1;
});
Here's a working fiddle.
If you're supporting an older version of javascript (eg. older browsers) you'll need to use "var" instead of "const" and use a "for" loop instead of the "forEach" loop shown above.
Why does this fail?
The way I read this code is "if either a or b or c equals three, then the statement is true". But apparently JavaScript disagrees. Why?
function test() {
var a = 'one';
var b = 'two';
var c = 'three';
return ( ( a || b || c ) === 'three' );
}
EDIT: am aware of the fact that i need to evaluate each expression separately, but was looking for a quicker way to write it. any suggestions will be welcome.
Your reading of the code is incorrect. Translated to a different form:
if (a) {
return a === "three";
}
if (b) {
return b === "three";
}
if (c) {
return c === "three";
}
The subexpression (a || b || c) returns the first of a, b, or c that is not "falsy". That's a, because its value is "one", so that's the overall value that's compared to "three".
The expression ( a || b || c ) returns anything that is truthy on the first-come-first served basis.
Here a is truthy and hence used. If a is falsey b will be used. If it is falsey too, c will be used.
So, you always end up comparing "one" == "three" since strings are considered truthy. You can make use of Array.some in this case, which does what you want or how you want it to behave, in your words
"if either a or b or c equals three, then the statement is true"
return [a,b,c].some(function(str){
return str == "three";
});
This evaluates to is a, b, or c (which will be true or false) the string-equivalent of "three". Which will always be false.
In order to achieve what you want, you need
return (a === 'three') || (b === 'three') || (c === 'three');
In C I know true and false evaluate to 1 and 0 respectively. show in this case just prints to the screen... Not sure what's going on here. I'm expecting to get true back. This 1 is messing up my karma.
show(1 && true);
true
show(true && 1);
1
Simply put - that's how && is defined. In Javascript, a && b returns a if a is falsy and b if a is truthy.
Conversely a || b returns a if a is truthy and b if a is falsy.
This makes sense intuitively - if a is false in a && b, then why bother reading the rest of the expression? You already know the whole thing is false. So just return false. But Javascript makes the decision to return a, which is falsy, instead of making up the value false to return out of nowhere.
This is based on short-circuit evaluation common to all C-style languages.
It allows for much expressiveness in Javascript. For instance this pattern:
var foo = function(opts) {
opts = opts || {}
// ...
}
Implements an optional parameter opts. If opts is not passed in at all, opts = opts || {} will set opts to {}, so the rest of the code does not have to know opts wasn't passed.
In long-hand it is equivalent to the following:
var x = a || b; // is equivalent to
var x;
if(a) {
x = a;
}
else {
x = b;
}
and
var y = a && b; // is equivalent to
var y;
if(!a) {
y = a;
}
else {
y = b;
}
Therefore Javascript can be much more terse than C or Java, because simple if statements can be replaced by || or && entirely. Sometimes this makes the code more terse and less readable and more like Perl, other times it allows for new Javascript patterns, like opts = opts || {}.
Another use is in patterns like
var displayName = user.fullname || user.email;
Which means "use the full name if available; if not, fall back to email." I personally find this expressive and readable, but it's arguably terse and obscure depending on which part of the Javascript community you hail from. Because of examples like this, and essentially the fact that truthy values are far more diverse then falsy values, using short-circuit || is much more common than short-circuit &&, as in your question.
What can be the most efficient way to find an item in an array, which is logical and understood by a web developer?
I came across this piece of code:
var inArray = function(a, b, c, d) {
for (c in b) d |= b[c] === a;
return !!d
};
It works fine. Can someone please explain me the code?
I also came across an exact same question that might make mine as a duplicate. But my real question lies in explanation of the above code and why bitwise operator has been used into it.
Also, can there be a way without any for loop, or iteration to get index of an item in an Array?
var inArray = function(a, b, c, d) {
for (c in b) d |= b[c] === a;
return !!d
};
That is some terrible code, and you should run away from it. Bitwise operators are completely unnecessary here, and c and d being parameters makes no sense at all (as Raymond Chen pointed out, the author of the code likely did it to safe space of declaring local variables -- the problem though is that if true is passed in for d the code is suddenly broken, and the extra parameters destroys any sense of understanding that glancing at the declaration would provide).
I'll explain the code, but first, here's a better option:
function inArray(arr, obj) {
for (var i = 0; i < arr.length; ++i) {
if (arr[i] === obj) {
return true;
}
}
return false;
}
Note that this is dependent on the array being an actual array. You could use a for (k in arr) type loop to generalize it to all objects.
Anyway, on to the explanation:
for (c in b) d |= b[c] === a;
This means that for every key in b (stored in c), we will check if b[c] === a. In other words, we're doing a linear scan over the array and checking each element against a.
d |= val is a bitwise or. The bits that are high in val will be set high in d. This is easier to illustrate in languages where bits are more exposed than in JS, but a simple illustration of it:
10011011
01000001
--------
11011011
It's just OR'ing each individual bit with the same location bit in the other value.
The reason it's an abuse here is that it convolutes the code and it depends on weird implicit casts.
x === y returns a boolean. A boolean being used in a bitwise expression makes little sense. What's happening though is that the boolean is being converted to a non-zero value (probably 1).
Similarly, undefined is what d will be. This means that d will be cast to 0 for the bitwise stuff.
0 | 0 = 0, but 0 | 1 = 1. So basically it's a glorified:
for (c in b) d = (d || (b[c] === a));
As for !!x that is just used to cast something to a bool. !x will take x, implicitly cast it to a bool and then negate it. The extra ! will then negate that again. Thus, it's likely implicitly casting to a bool (!!x being true implies that x is at least loosely true (1, "string", etc), and !!x implies that x is at least loosely false (0, "", etc).
This answer offers a few more options. Note though that all of them are meant to fallback to the native indexOf that will almost certainly be faster than anything we can code in script-land.
This code is pretty poorly written, and barely readable. I wouldn't qualify it as "awesome"...
Here's a rewritten version, hopefully more readable:
function inArray (aElt, aArray) {
var key;
var ret = false;
for (key in aArray)
ret = ret || (aArray[key] === aElt);
return ret;
}
The for loop seems like the most natural way to do that. You could do it recursively but that doesn't feel like the easiest approach here.
What can be the most efficient way to find an item in an array, which is logical and understood by a web developer?
Either the native method, haystack.indexOf(needle) !== -1 or a looped method which returns as soon as it can
function inArray(needle, haystack) {
var i = haystack.length;
while (i) if (haystack[--i] === needle) return true;
return false;
};
You asked for a recursive version
var inArray = function(arr, needle, index) {
index = index || 0;
if (index >= arr.length)
return false;
return arr[index] === needle
? true
: inArray(arr, needle, index + 1);
}
console.log(inArray([1,5,9], 9));
I'm reading some code and I see a comparison that's laid out like this:
a = b = c
Seeing as how searching Javascript about equal or comparison yields remedial results, anyone care to explain what's going on?
EDIT: These are all objects or object properties that we're talking about here, should have specified.
DOUBLE EDIT: This is inside of an Object.defineProperties() block.
= is an operator. It takes two arguments: a variable reference and an expression. It assigns the value of the expression to the variable, and returns the assigned value.
As a result, you can chain them and it equates to this:
a = (b = c)
In other words, assign b to the value of c, then assign that value to a also.
a = b = c is just shorthand expression for:
b = c;
a = b;
if(a = b) will always return true because it is assigning, instead of comparing. To compare, the statement should read: if(a == b).
The = operator associates right-to-left and evaluates to the value that was assigned.
So this:
a = b = c;
Means this*:
b = c;
a = c;
* Unless you're dealing with properties.
That is not a comparison. It is an assignment of the value of c to the b and a variables.
Assignment works right to left, so it is an assignment of c to b first. Then the return value of that operation is assigned to a.
The return value of an assignment operation is the value that was assigned, so a will get the same value assigned to b.
It equates this;
b = c; a = b;