Surprising value assignment due to operator precedence? - javascript

Original question based on completely wrong logic :O
$(function() {
var x=0,y=1;
$("#div_id").find("input:text").each(function (i, input) {
$(this).val(""+(i % 2 == 0)?x++:y++);
});
});
If I remove the ""+ from the value, I get this wrong result
instead of what I want, which is this:
Same if I use prop:
$(this).prop("value",""+(i % 2 == 0)?x++:y++);
Same if I prefix the ++
What am I overlooking? Is this an obvious thing?
UPDATE: I completely missed the boat here.
Here is the code I meant to write and it works without the ""
$(function() {
var x=0,y=1;
var inputs = $("#div_id").find("input:text");
var y = Math.ceil(inputs.size()/2);
inputs.each(function (i, input) {
$(this).prop("value",(i % 2 == 0)?++x:++y);
});
});

"" + (i % 2 == 0) ? x++ : y++
is interpreted as (see precedence rules)
("" + (i % 2 == 0)) ? x++ : y++
and ("" + (i % 2 == 0)) is always truthy, because both "true" and "false" are non-empty strings. So in your example, you're using x++ all the time, ignoring the y++ branch.

It seems the associativity of + operator which is from left to right of expression. If you remove ""+ only (i % 2 == 0) makes condition part of conditional operator which will be evaluated to true of false. but if you include it will not evaluated to boolean rather string and would be true always.
With string you will always get true
alert("" + false ? "true" : "false");
Live Demo

Related

Javascript check if a decimal is negative

How would i check if a decimal is negative? Because the if statement automatically turns it into a number...
Example:
var x = -0.24324;
how would i parse it so it tells me x is negative/positive?
Thanks
Edit: Maybe i phrased it badly, the variable changes so something it will be positive like 0.00000001, sometimes -0.0003423423, sometimes 0.0000000234
If i put it in a if statement everything is automatically turned into 0 right? And i can't use a parseFloat in the if statement?
Just check if x less than zero since it's a number:
if (x < 0) {
// it's negative
}
You can use isNaN() function to check whether it is valid number or not.
If it is, then you can check for positive or negative value.
Something like this:
var x = "-123"
var y = -456;
var z = '-123a';
if(!isNaN(x) && x < 0) {
console.log(x + ' is negative');
}
if(!isNaN(y) && y < 0) {
console.log(y + ' is negative');
}
if(!isNaN(z) && z < 0) {
console.log(z + ' is negative');
}
const num = -8;
// Old Way
num === 0 ? num : (num > 0 ? 1 : -1); // -1
// ✅ ES6 Way
Math.sign(num); // -1

javascript string expression as if condition

I am building a string which is to be evaluated as if condition, like
if (location_val.length == 1) {
condition = condition + " v.location === '" + location_val + "' &&";
} else {
for (var i = 0; i < location_val.length; i++) {
condition = condition + " v.location === '" + location_val[i] + "' && ";
}
}
but javascript evaluates the variable if it is not null, undefined, 0 or empty string, how to evaluate string as expression? I am using condition variable as follows, but it always returns true because of the above reason.
if(condition)
Build your expression properly - not using string concatenation, its something like this:
var condition = (location_val.length == 1 && v.location == location_val)
|| (location_val.every(function(loc){ return v.location === loc; } );
if(condition) {
....
}
I suspect there is more to this (you have && at the end of both strings) but the same applies to everything else. Boolean's can be combined in parts
var condition1 = (location_val.length == 1 && v.location == location_val)
|| (location_val.every(function(loc){ return v.location === loc; } );
var condition2 = ...
var condition3 = ...
if(condition1 && condition2 && condition3){
....
}
In JavaScript there's the eval function. You can use it to evaluate a string as an expression.
eval('3 + 2 === 5') //true
I would recommend you to rethink your solution, though, since working with strings as expressions when you could solve your problem differently, is really error prone and literally the worst practise.
Also use === instead of ==
(=== works as you'd expect == to work, == doesn't)

Why is `exp && "t" || "f"` much slower than inline-if-else?

Why is the logical expression twice slower than if-else or inline-if-else?
function logicalExp(val) {
return val && "t" || "f";
}
function inlineIfElse(val) {
return val ? "t" : "f";
}
function ifElse(val) {
if (val) return "t";
else return "f";
}
All functions evaluate with same results.
All functions are being passed a value from an array of 1 and 0, see this jsperf test.
Because it does need to evaluate whether "t" is truthy or not. The short-circuit expression return ((val && "t") || "f") can be expanded to
var and = val ? "t" : val;
var or = and ? and : "f";
return or;
Of course, an optimising compiler could statically determine the truthiness of the "t" literal, and avoid doing ToBoolean(val) twice, but apparently this is not done in any JS engine.
Because
val && "t" || "f"
has to evaluate val and, if val evaluates to true, "t" as well.
Using only false is therefore significantly faster than only true, but still quite slow.

Boolean expressions - getting mixed up with AND, OR logical operators and how they work

I have to convert a number to comma format. E.g 12345 => 12,345.
I have my solution :
function convert(n) {
n = n.toString();
var result = '';
var count = 0,
var idx = n.length - 1;
while (r = n[idx]) {
count++;
result = ((count % 3 == 0 && count != n.length) ? ',' : '') + r + result;
idx--;
}
return result;
}
But someone else used :
result = ((count % 3 != 0 || count == n.length) ? '' : ',') + r + result;
They both work but now I am confused about my own solution and just lost why they both work. Ah not sure if my question is clear.
!(x AND y) is equal to !x OR !y
(and you can pull a NOT out of a boolean x by double negation, for example:
x == !!x
so
x AND !y (your original expression) is equivalent to !(!x OR y)
if you remove the negation (!) from the beginning, then you actually get the Negated form and that is why the second and third values of the ternary operator are reversed in your second example.
The two expressions are equivalent, the second one is just the negated version of yours. The opposite (more or less) of == is !=, the opposite of && is ||, and the opposite of true is false.
You are placing a comma whenever the count is divisible by 3 and you aren't at the start of the number. They are not placing a comma anytime the count is not divisible by 3 or they are at the start of the number.
Assume that, count % 3 = 0 and count > n.length
Now your logic:
((count % 3 == 0 && count != n.length) ? ',' : '')
which means True && True which results in True hence the first condition after ? which is "," is selected.
Someone else logic:
((count % 3 != 0 || count == n.length) ? '' : ',')
which means 'False || False' which results in 'False' hence second condition after ? which is "," is selected.
P.S: Both are using similar logic

Question mark and colon in JavaScript

I came across the following line
hsb.s = max != 0 ? 255 * delta / max : 0;
What do the ? and : mean in this context?
It is called the Conditional Operator (which is a ternary operator).
It has the form of: condition ? value-if-true : value-if-false
Think of the ? as "then" and : as "else".
Your code is equivalent to
if (max != 0)
hsb.s = 255 * delta / max;
else
hsb.s = 0;
Properly parenthesized for clarity, it is
hsb.s = (max != 0) ? (255 * delta / max) : 0;
meaning return either
255*delta/max if max != 0
0 if max == 0
This is probably a bit clearer when written with brackets as follows:
hsb.s = (max != 0) ? (255 * delta / max) : 0;
What it does is evaluate the part in the first brackets. If the result is true then the part after the ? and before the : is returned. If it is false, then what follows the : is returned.
hsb.s = max != 0 ? 255 * delta / max : 0;
? is a ternary operator. It works like an if in conjunction with the :
!= means not equals
So, the long form of this line would be
if (max != 0) { //if max is not zero
hsb.s = 255 * delta / max;
} else {
hsb.s = 0;
}
?: is a short-hand condition for else {} and if(){} problems.
So your code is interchangeable to this:
if(max != 0){
hsb.s = 225 * delta / max
}
else {
hsb.s = 0
}
MDN - Conditional (Ternary) Operator
? : isn't this the ternary operator?
var x= expression ? true:false
What you are referring to is called a ternary operator, it is essentially a basic if condition check that can be written to execute an operation if the block of code within the ternary operation is valid, otherwise default to a fallback.
A ternary operation is written in the following syntax:
condition ? exprIfTrue : exprIfFalse
condition An expression whose value is used as a condition.
exprIfTrue An expression which is evaluated if the condition evaluates to a truthy value (one which equals or can be converted to true).
exprIfFalse An expression which is executed if the condition is falsy (that is, has a value which can be converted to false).
Example
Take the given function below which should return the string Yes if the number provided to the function is even, otherwise return No.
function isEven(num) {
return (num % 2 == 0) ? "Yes" : "No";
}
console.log("2: " + isEven(2));
console.log("3: " + isEven(3));
Explanation
The operation above broken down:
(num % 2 == 0) | This is a simple if statement condition to check if the expression within the brackets is true.
? "Yes" If the operation is true, the string literal given is automatically returned as a result of this execution.
: "No" This is the else clause in this operation, if the condition is not met then No is returned.
Be careful with this. A -1 evaluates to true although -1 != true and -1 != false. Trust me, I've seen it happen.
so
-1 ? "true side" : "false side"
evaluates to "true side"

Categories

Resources