The so called
modulus operator, which is represented by the very same symbol as the percentage symbol namely
%, has the purpose of emulating a division.
Namely both an expression like a straightforward division:
10/2
and an expression involving the modulus like:
10%2
perform a division, whereas the difference between the standard division and a division performed by a
modulus emblem is that the former returns the result, the latter (the one performed by the modulus) returns the
remainder of such division, or zero if no remainder is left.
Try testing below, then change second field value to a number that perfectly divides the first, for instance 1:
The modulus division is often performed to verify whether a number is odd or even: dividing by the modulus operator any number by 2, namely
num%2, if the returned value is zero the number is even, otherwise is odd.
So, since the modulus calculation can return zero if the divisor perfectly divides the dividend without generating any reminder, many scripters are used to nest such an operation within a conditional test to check whether it returns
true (a reminder is present) or
false (no remainder is present: zero).
Of course, a shorthand to signify you want to check whether a conditional statement returns false is to pre pone to it a
! sign, namely:
if(! ... ) { ... } which means: if the statement within the round brackets holds
false, execute the statements inside the immediately following curly brackets set.
Therefore some scripters attempt to verify, for instance, the evenness of a number like follows:
if(! number%2){ alert('Even number!') }
assuming that if the remainder is zero, then would return false and trigger the alert (the conditional statement prescribes that the returned value has to be false, in order to execute the next code).
But with their extreme, and in my opinion right, puzzlement the scripters see that the statement doesn't work the expected way: inserting 2 as number and dividing it by 2 positively yields no reminder, none the less the statement doesn't trigger the alert.
if(! )
The code above would
always return
true regardless of whether the modulus operation returns a
remainder (
true) or none (zero, namely
false); consequently, it would
never trigger the block subsequent such conditional statement, so it would never work the expected way. Why?
Try inserting as first number 0, namely try 0%2: the expression would finally return false only in this case. What's happening?
The fact is that the modulus operation doesn't return an
eventual result: that is, the
modulus division is not first calculated and then the returned result passed for the check. Bewildering as it can be, the modulus returns... the first element before the modulus itself!
Note that this is a quirk indeed: in fact all operations nested within conditional statements are
first computed, then the eventual result passed to the evaluation.
And I do can prove it, and therefore that it is
irrational:
If you write:
if(! 2-2 ){alert('SUBTRACTION result is zero')}
The expression triggers the alert.
But if you write
if(! 2%2 ){alert('MODULUS result is zero')}
the expression does
not trigger the alert: but
both expressions return zero!
Test it
yourself, click the button and it will evaluate both expressions nested in the textarea below (they are the same expression just mentioned, one a modulus the other a subtraction operation)
Consequently, what's obviously happening (obviously to the deduction, not in itself as a fact!) with a
modulus division s that the operation to be performed within the conditional statement check is not first reckoned and
then passed to the evaluation check (as the normal and logic procedure prescribes!), but that the evaluation gets performed
at some earlier stage, before the modulus operation is actually computed; which stage?
The stage of the first number: evidently, an expression like:
if(! %2 )
is not read as:
if (make computation) is false, then trigger the alert
but gets read as:
if () is false, then make the computation, then trigger the alert
The latter operation would always return true, unless the number is by chance zero itself, because checking whether a number which is
not zero is false (false and zero are synonyms in programming languages!), would
always and invariably return true: 2 is not zero, so it is true!
Solution: nest the modulus operation in within
another set of brackets, to stress that you do want to execute what is inside them before passing the whole of it to the check of the conditional statement:
if(!(2%2)){alert('MODULUS result is zero')}
Blatant evidence of this:
The reason behind all this can actually be found, was stated by me -as it is to be stated below here- in an italian scripting newsgroup, and boils down to this (thanks to Josh for having rememberd me of this implication, for though I posted it on the italian newsgroup, upon writing this file two months later I firstly forgot to add it here too):
the
! operator is evaluated
first in
both cases and the
yielded boolean value is what gets involved in the methematical operation; that is, the operator
! is never evaluated against the whole statement, but always only against the
first element of the statement (unless furhter round brackets meddle to insulate segments and rearrange the default precedence order), and since such element is
number 2, wondering by that operator
! whether 2 is
false yields... false: the
! just sticks onto the first number 2:
!2
means asking:
is 2 false?
Since it is
not, what is returned is
false, and thus
if(!2-2)
means:
if(false-2)
Needless to say this causes endless misunderstandings even with experienced programmers:
(!2-2) is (false-2) yields -2, so triggers the alert
(!2%2) is (false%2) yields 0, so triggers no alert
That is, the operator returns (and
assigns!!)
false in both cases, and such
false is
what is computed against the subsequent number!
Now call it all
obvious if you dare.
Yet, we still have disturbing implications. Consider the following:
if(!2-2){alert('example 1a')}
as we saw that boils down to:
if(false-2){alert('example 1b')}
If you test it, all the alerts get triggered for the keyword
false when
forced within a mathematical operation is
converted into a zero, and so the expression turns into a boilerplate:
0-2=-2
And since the yielded
-2 is a number which positively and undoubtedly exists (it is not a zero, that is), the
conditional statement returns true (something... exists), and triggers the alert: the
! operator is as if it would be sticking with the number,
not with the
whole expression.
Yet, you are
induced to believe that what returned
false was the
whole subtraction, for 2 less 2 yields zero which in programming languages always tantamount to false, and that
this latter computation was evaluated against the boolean operator
!. But it was
not that, it was a thoroughly different operation what got actually performed:
NOT wondering whether:
if 2-2 is zero
BUT wondering whether:
if false-2 yields a reminder
SAME outcome but
thoroughly different underlying reality, and if you don't experience a sense of puzzlement before this unmeant coincidence, a bewildering concurrence between what you thought was going on and the result produced by what truly happened, and you don't feel your scripting practices jeopardized, that must be because you're used to program by route, learning by heart your formulas without any critic mindset - that is, without having understood them: which is called
ignorant competence.
That the precedence of the operators (meaning here by operators the boolean operator represented by the
! symbol) should be in place and a
! sign should therefore be parsed before anything else, as a form of reverence for its "status", is a possible argument some raised, but to no use as long as you don't focus on the reasons and the whys and the whereofs acknowledging they do involve
something puzzling and you limit yourself to state the point. On an italian newsgroup an alleged expert who lectures all and looks everybody upon down firstly couldn't provide
any of these explanations whatsoever for the behaviour of the modulus, and once I provided it alleged it was "
obvious" upon "operator precedence" issues and this was the reason he didn't provide it, liquidating the topic as solved - by (a-hem sorry)
me... talk of having understood it not, but having to pretend you did. If there is something all this lacks is
precisely obviousness.
In fact such an alleged explanation is of no validity if not elaborated paying justice to the involvements, insofar operators get apparently granted this priority at one time (with the modulus, namely the operator check is performed prior to the performing of the operation), whilst at another time (with the subtraction, or whatever else mathematical operation for that matter) they don't apply it the same way any longer (that is, first the operation gets computed, then the
outcome is checked), and
all the way they may induce you to rightly believe something else was going on (this else being
obvious indeed, for the obvious is in this forthcoming latter not in that former):
that 2-2 yields zero, and
such outcome would have been what would have got compared against the boolean operator!
I call it immensely subtle, and
not obvious at all:
«Only the amateur discovers the truth. (...)
Audacity, freshness, originality and all the virtues of the talented thinker, whose opposite is not really the well prepared or methodic man, but it is actually the pedant.
A talented thinker, like a poet, continuously restarts and exposes himself, so to recover that condition of innocence and ingenuity which favors the discovery.»
[Benedetto Croce]
This is why I like beginners, and why beginners love me: I feel anew in myself all their puzzlement as if it were mine, and I partake of it afresh, without disdain or snubbing.
If you don't explain why things happen, because you never asked yourself the questions because such questions didn't even come to your mind and you never palpitated with the expectation they ignite, this is merely a sure fire recipe to make your scripters lose their minds for many sleepless nights, in the name of a purely theoretical explanation which explained nothing, or in the name of that weird attitude which wants us not to acknowledge that something makes little sense (sort of a
taboo of the "guru"), while
facts just went on having it their own way.
While in Rome they speculate, Saguntum got stormed.
An Array is a set of digital data arranged in a line of slots, like pearls in a necklace: each bead can be addressed by a number (from
zero onward, accordingly to their position in the sequence) and deliver the value that was connected in that position (like, say, asking what is the colour of the bead in position 5).
Looping an array by a traditional
for loop would reveal that if you inspect the
data type the index of each parsed bead is, it would correctly report it is a
Number.
But if you make the same with a
for-in loop, it would report it is a...
String. Test it:
The fact is: all indexes in within an Array are actually strings indeed.
As for what an number which is a string would mean, well you know: if you sum:
1+1=2
you certainly get a number as a result; but if you sum:
"a"+"b"=ab
namely two letters (positively: strings!), then a+b gives the sequence of the two letters as their "sum", not a third entity meant to synthesize the addends; likewise a number in between quotes stops being conceived as a number and starts being handled as a letter is.
But as I said, all indexes of an array are actually string data type: you have nothing else to do than take it for granted despite it sounds puzzling: the standard for loop reports
number simply because you're not checking the real indexes of the Array but the iterator
i which you yourself have
initialized as a number:
for(var ; i < foo.length; i++){alert(typeof i)}
I understand it is difficult to cope with this once you've used these loops for a lifetime and you've got persuaded that the indexes of an Array couldn't be but numbers: the fact is, they are
not: they are strings.
If anyway you want to delve deeper, if you're wondering how comes an index which is a String is responsive to a probe which is a Number, well for more on the subject, an interesting perspective with a good external contribute is on
this file of mine (click).
Behold and awe:
when in javascript you call a property or a method, you can omit the reference to the
window object:
window.location
can therefore be just: location.
So, since window is the uppermost object in the javaScript kingdomship, in the javaScript hierarchy, it is
always
rightly assumed and safely presumed; and so you can omit it.
But as soon as you go one step down the ladder of the javascript hierarchy, all
objects
should
carry a fully qualified path reference to the parent which contains them:
therefore
document.images['name']
is correct, for it names the document, within which the image is embedded and lives its virtual life.
Also, even the simpler statement (although not yet as much simpler as just imageName will be!)
document.imageName
should not work, for when after the keyword document you insert a name
that isn't the keyword name of a pre-defined collection of objects (such as, for instance, document.links, document.images, document.anchors, document.forms) then javaScript would expect, by default, a form object; in fact, javascript allows only for these two fore mentioned shorthands: omitting any reference to the window topmost object which as such can safely be considered as always and invariably implied, and putting a bare name after the keyword document, which every javaScript interpreter considers then as a reference to a form name and to a form name alone.
None the less, you see that
<img src='foo.gif' name='imageName' onMouseOver="imageName.src='newfoo.gif'">
does work, although the document reference has been unsafely and completely omitted.
In fact, if you attempt:
<img src='foo.gif' name='imageName' onMouseOver="imageName.src='newfoo.gif'">
<script>alert(imageName.src)</script>
the alert in the script tag, namely outside the img tag, would fail locating the
object and guessing what you could have meant, even if the onMouseOver inside the img tag would conversely work, and with the very same syntax.
It has been argued (in a really intelligent way in my opinion, one of
the
most valuable arguments I ever saw on a newsgroup) that when an event handler (such as onMouseOver) calls a
property or a method,
javaScript can guess that an anonymous reference may involve by default
the
immediate parent
object which belongs to the object the event has been deployed and dispatched into: namely the img tag. Therefore it
has been rightly argued
such shorthand syntax in an image tag can deduce, can understand it is meant as referred to that very same object the tag represents. It is a guesswork by the digital interpreter that, at least, could make sense.
For your convenience I report in this textarea the reply I got for I find it extremely intelligent (I do not know the name of the Author, who signs himself/herself as just Yaz), one of the sounder answers I ever got on a newsgroup: