why Operator precedence `and` higher then `or` - javascript

in https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence
if and higher then or,1||alert(1)&&alert(2) will alert but no
I think they are the same

Looking at the expression:
1||0&&2
The expression is the same as the following:
1||(0&&2)//because && has greater precedence than ||
In which case 1 is the truthy value so you get 1.
So, with precedence rule this is not going to be like below:
(1||0)&&2//because || has lesser precedence than &&

The reason is simple, multiplications come before additions and I hope you know that... The and is a logical product and the or is a logical addition.
So with logical operators you could rewrite your operation (a||b&&c) such as:
a + b * c
and if a, b, and c are Boolean and you apply the proper Boolean operation, it gives you the right result. You can translate that to one bit binary if you'd like:
&& => 1 * 1 is true, all others are false
|| => 0 + 0 is false, all others are true

why Operator precedence and higher then or
Because that is how the language is defined. If it bothers you, then feel free to parenthesize to make the grouping clear.
Many other languages work this way.
A rule for remembering which has higher precedence is to think of && as multiplication and || as addition (which they are, in a logical sense). Of course, multiplication has higher precedence (binds more tightly) than addition.

Related

Please what does mean this : if (a && b == c){};?

Please what does mean this:
if (a && b == c){};
I did not understand the logic of the condition statement
&& has lower precedence than ==, so it's equivalent to:
if (a && (b == c))
It means if a has a truthy value and also the value of b is equal to the value of c.
The condition (a && b == c) has two operators. The Logical AND Operator and the Equality Operator.
The operation foo && bar returns true, if both operands foo and bar have truthy values.
foo == bar returns true, if foo equals bar.
The equality operator converts the operands if they are not of the same type, then applies strict comparison. If both operands are objects, then JavaScript compares internal references which are equal when operands refer to the same object in memory.
If an expression contains more than one operator, the operator precedence is of the utmost importance.
Operator precedence determines the way in which operators are parsed with respect to each other. Operators with higher precedence become the operands of operators with lower precedence.
The == operator has a higher prededence than the && operator. Therefor the above condition will check b == c first. If the result is true and the value of a is truthy, the result of the condition will be true.
The Grouping operator ( ) has the highest precedence and therefor can be used to force a specific order of operations.
If you're not absolutely sure in which order operations will be processed, use the grouping operator!
The result of
(a && (b == c))
will be the same as the result of
(a && b == c)
but is better readable. Of course you should learn and know the precedence of operators. But if in doubt and especially in a really hairy line with lots of operators, the value that a few brackets add to readability can easlily outperform the costs of a few bits of additional code.

How does this check work with operator precedence in JS

So I'm reading through this precedence table https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence
It says 20 - 1 with 20 being highest precedence.
16 Logical NOT right-to-left ! … So the ! operator has a precedence of 16.
10 Strict Equality … === … So the === operator has a precendence of 10.
This lines
!'hello' === 'goodbye'
How does this get executed/read? By reading it I thought. In steps it goes;
'hello' === 'goodbye' Check then, invert bool value. So If it returns true set it to false.
If i'm reading through the precedence operators table. It looks to me like it does the ! operator first and then ===.
How does it invert a non-bool value beforehand and then do the truthy check? Like how does it work could someone explain?
Thank you!
It looks to me like it does the ! operator first and then ===.
Yes. 16 is a higher number than 10, so ! has a higher precedence than ===, so it is resolved first.
How does it invert a non-bool value beforehand and then do the truthy check?
See the spec for ! which points to ToBoolean which says:
String: Return false if argument is the empty String (its length is zero); otherwise return true.

What is this asm style "x | 0" some javascript programmers are now using?

I've seen some performance critical javascript code, like the one on this project that makes extensive use of bitwise OR operations with 0. Ex:
GameBoyAdvanceCPU.prototype.write8 = function (address, data) {
address = address | 0;
data = data | 0;
this.memory.memoryWrite8(address | 0, data | 0);
I know about the use case of flooring numbers with "|0", but that isn't the case here, as these are always int's. It looks a bit like asm.js, is this to tell the js engine that we are working with integers, allowing some optimizations? If so, which browsers will make those optimizations?
Any pointers to how this works would be appretiated.
According to JavaScript Performance for Madmen
Wrapping integer arithmetic expressions in ( ) | 0 allows the runtime to be sure that you're doing integer arithmetic instead of floating-point arithmetic. This allows it to avoid checking for overflow and produce faster code in many cases.
and according to the page, it's true for "most" Javascript runtimes, but doesn't say which.
As a second source, Writing Fast JavaScript For Games & Interactive Applications states
To tell JavaScript engine we want to store integer values [...] we could use bitwise or operator:
and a third source from Microsoft's Writing efficient JavaScript page:
[...] explicitly tell the JavaScript runtime to use integer arithmetic [...] use the bitwise or operator
Also, apart from in comments, none of the pages above mention asm.js, so I suspect such optimizations apply in code not explicitly marked as asm/in browsers that don't explicitly recognize it.
Referencing the Ecmascript 5 spec: 11.10 Binary Bitwise Operators, namely
The production A : A # B, where # is one of the bitwise operators in
the productions above (&; ^; |), is evaluated as follows:
Let lref be the result of evaluating A.
Let lval be GetValue(lref).
Let rref be the result of evaluating B.
Let rval be GetValue(rref).
Let lnum be ToInt32(lval).
Let rnum be ToInt32(rval).
Return the result of applying the bitwise operator# to lnum and rnum. The result is a signed 32 bit integer.
And noting that ToInt32() is defined as
Let number be the result of calling ToNumber on the input argument.
If number is NaN, +0, −0, +∞, or −∞, return +0.
Let posInt be sign(number) * floor(abs(number)).
Let int32bit be posInt modulo 2^32; that is, a finite integer value k of Number type with positive sign and less than 2^32 in magnitude such that the mathematical difference of posInt and k is mathematically an integer multiple of 2^32.
If int32bit is greater than or equal to 2^31, return int32bit − 2^32, otherwise return int32bit.
It then logically follows (which you can confirm in your own console) that for example
((Math.pow(2, 32)) + 2) | 0 === 2
(Math.pow(2, 31)) | 0 === -2147483648 === -(Math.pow(2, 31))
And so forth.
Shortly put, the operation turns the number to a 32-bit integer (which has its knacks, see the second example above and the ToInt32() definition for an explanation) and then does a logical or with zero which doesn't change the output beyond the first conversion.
Essentially it's a very cost-efficient way to turn a number into a 32-bit integer because 1) it relies on browser's built-in ToInt32(); and 2) ToInt32(0) short-circuits to 0 (see the spec above) and therefore adds practically no additional overhead.
What it actually does can be seen in this fiddle
It's probing the variable against integer type in this case and either "flooring" or set it to 0 if not an integer.
Thus, there's a tremendous differnece to a = a || 0 which would leave a value of 3.2 untouched.
| operator is bitwise OR. It's used to do a bit by bit OR operation on two integers.
The usage here is a shortcut very similar to logical OR || operator to provide default value, with the exception that the result is integer only (as opposed to string...etc)
address = address | 0;
means "if address is a number, let's use it; otherwise, set it to 0".

Perils of <= and >= in Javascript. How to avoid them?

Bill the Lizard stated the dangers and cons of using the equality operator (==) in this answer. However, little has been said about the undercover "evil twins", the >= and the <=.
0 >= '' // true
0 <= '' // true
'' >= 0 // true
'' <= 0 // true
Therefore, my questions are:
Should elements of different types be comparable by default?
1.1 If not, what should be the returned value? false? undefined? Bear in mind that if a >= b === false, this implies that a < b === true.
What could be done to avoid, in a practical way, odd cases as the ones in the example?
Since greater than (<) and less than (>) operators also do type conversion, are there any odd cases for them?
Should elements of different types be comparable by default?
This only matters if you are designing a language. In JavaScript, values of different types are comparable, and comparison follows certain rules. You have to be aware of them, but I don't see any point in discussing "what if the rules were different".
What could be done to avoid, in a practical way, odd cases as the ones
in the example?
Just avoid comparing values of different types, it doesn't make sense if most cases. The only situation where it's useful is comparing numeric strings with numbers. And in that case JavaScript behaves just as anyone would expect, no odd results.
Since greater than (<) and less than (>) operators
also do type conversion, are there any odd cases for them?
I'm sure there are, although I can't think of one right now. But why you think your examples are odd? You seem to understand that "" == 0 because of type conversion, so it's no wonder all the comparisons in your example return true, as they all include zero.

Does operand order make any difference when evaluating equality or identity in JavaScript?

Question: does operand order make any difference when evaluating equality or identity in JavaScript?
In code, is (0 == value) faster or more correct than (value == 0)? (Note that this question is equally valid for the identity operator, ===.)
Since both the equality and identity operators are commutative, I don't believe the operand order should make a difference in evaluation performance, unless there's some inherent benefit to the left-side literal in the computation of the equality algorithm itself. The only reason I wonder is that I recently used Google's Closure Compiler to boil down some JavaScript, and noticed that
if (array.length == 0 && typeof length === 'number') {
had been compiled to
if(0 == b.length && "number" === typeof c) {.
In both equality expressions—one loose and one strict—Closure has reversed the order of my operands, placing a Number literal and a String literal on the left–hand sides of their respective expressions.
This made me curious.
I read through the Equality Operators section of the ECMAScript 5.1 Language Specification (section 11.9, pp. 80–82) and found that while the equality algorithms start by examining the left–hand operands first, there's no indication that it's faster or better to use a literal as that operand.
Is there something about ECMAScript's type–checking that makes examination of literals optimal? Could it be some optimization quirk in the Closure compiler? Or perhaps an implementation detail in an older version of ECMAScript's equality algorithm which has been nullified in this newer version of the spec?
A lot of time people code with the variable on the right as a style convention. Main reason it can catch errors with sloppy coding.
The following code is most likely a bug, but the if statement will evaluate to true.
if( n = 1 ) { }
and this will throw an error
if( 1 = n ) { }
http://jsperf.com/lr-equality
I can't really give you an explanation, but you can check the numbers. They seem to be equal (now).

Categories