var attr = ~'input,textarea'.indexOf( target.tagName.toLowerCase() )
? 'value'
: 'innerHTML'
Ich habe es in einer Antwort gesehen, und ich habe es noch nie gesehen.
Was heißt das?
var attr = ~'input,textarea'.indexOf( target.tagName.toLowerCase() )
? 'value'
: 'innerHTML'
Ich habe es in einer Antwort gesehen, und ich habe es noch nie gesehen.
Was heißt das?
Antworten:
~
ist ein bitweiser Operator , der alle Bits in seinem Operanden umdreht.
Wenn Ihre Nummer beispielsweise wäre, wäre 1
ihre binäre Darstellung des IEEE 754-Floats (wie JavaScript Zahlen behandelt) ...
0011 1111 1111 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
So ~
wandelt seine Operanden in einem 32 - Bit - Integer (bitweise Operatoren in JavaScript tun) ...
0000 0000 0000 0000 0000 0000 0000 0001
Wenn es eine negative Zahl wäre, würde sie im Zweierkomplement gespeichert: Invertiere alle Bits und addiere 1.
... und dreht dann alle seine Teile um ...
1111 1111 1111 1111 1111 1111 1111 1110
Was nützt es dann? Wann könnte man es jemals benutzen?
Es hat einige Verwendungszwecke. Wenn Sie Low-Level-Sachen schreiben, ist es praktisch. Wenn Sie Ihre Anwendung profiliert und einen Engpass festgestellt haben, kann sie durch bitweise Tricks (als ein mögliches Werkzeug in einer viel größeren Tasche) leistungsfähiger werden .
Es ist auch ein (allgemein) unklarer Trick , indexOf()
den gefundenen Rückgabewert in wahrheitsgemäß umzuwandeln (obwohl er nicht als falsch eingestuft wird ), und die Leute verwenden ihn häufig wegen seines Nebeneffekts, Zahlen auf 32 Bit abzuschneiden (und seine Dezimalstelle durch Verdoppeln zu löschen ). effektiv das gleiche wie Math.floor()
für positive Zahlen).
Ich sage unklar, weil es nicht sofort offensichtlich ist, wofür es verwendet wird. Im Allgemeinen möchten Sie, dass Ihr Code klar mit anderen Personen kommuniziert, die ihn lesen. Während die Verwendung cool aussehen~
mag , ist sie im Allgemeinen zu clever für sich. :) :)
Es ist jetzt auch weniger relevant, da JavaScript Array.prototype.includes()
und hat String.prototype.includes()
. Diese geben einen booleschen Wert zurück. Wenn Ihre Zielplattform (en) dies unterstützen, sollten Sie dies bevorzugen, um das Vorhandensein eines Werts in einer Zeichenfolge oder einem Array zu testen.
value = value || default
in JavaScript eine gebräuchliche und gültige Redewendung, solange Sie wissen, wann Sie sie verwenden können und wann nicht.
v = t ? a : b;
. Ich finde das viel klarer als var v; if (t} { v = a; } else { v = b; }
normalerweise über 5 Zeilen verteilt und auch klarer als var v = b; if (t) { v = a; }
normalerweise über 4 Zeilen. Aber ich kenne viele Leute, die mit den ? :
Betreibern nicht vertraut sind und den zweiten oder dritten Weg bevorzugen würden. Ich finde das erste ist besser lesbar. Ich stimme dem allgemeinen Prinzip zu, mache den Code klar, benutze keine Hacks. Ich denke, ich sehe ~v.indexOf('...')
nur sehr klar, wenn ich es gelernt habe.
~
idiomatisch nennen . es ist technisch Teil der Sprache spec , aber es ist nicht so sehr ein Teil der Sprache im allgemeinen Gebrauch .
Verwenden Sie es vor einem indexOf()
Ausdruck verwenden, erhalten Sie anstelle des direkt zurückgegebenen numerischen Index ein wahrheitsgemäßes / falsches Ergebnis.
Wenn der Rückgabewert ist -1
, ~-1
liegt es 0
daran, dass -1
es sich um eine Zeichenfolge aller 1 Bits handelt. Jeder Wert größer oder gleich Null ergibt ein Ergebnis ungleich Null. So,
if (~someString.indexOf(something)) {
}
bewirkt, dass der if
Code ausgeführt wird, wenn sich "etwas" in "someString" befindet. Wenn Sie versuchen zu verwenden.indexOf()
direkt als Boolescher Wert zu verwenden, funktioniert dies nicht, da manchmal Null zurückgegeben wird (wenn "etwas" am Anfang der Zeichenfolge steht).
Das funktioniert natürlich auch:
if (someString.indexOf(something) >= 0) {
}
und es ist wesentlich weniger mysteriös.
Manchmal sehen Sie auch Folgendes:
var i = ~~something;
Wenn Sie den ~
Operator zweimal so verwenden, können Sie eine Zeichenfolge schnell in eine 32-Bit-Ganzzahl konvertieren. Der erste ~
führt die Konvertierung durch und der zweite ~
dreht die Bits zurück. Wenn der Operator auf etwas angewendet wird, das nicht in eine Zahl konvertiert werden kann, erhalten Sie natürlich NaN
ein Ergebnis. ( Bearbeiten - eigentlich ist es die zweite ~
, die zuerst angewendet wird, aber Sie bekommen die Idee.)
~
ganzen Zahlen gleich -(x + 1)
.
0
Seins false
und des Nicht-Null-Seins true
reicht weit zurück, zumindest bis C in den 70er Jahren und wahrscheinlich viele andere damals moderne Systemprogrammiersprachen. Es liegt wahrscheinlich an der Funktionsweise der Hardware. Viele CPUs setzen nach einer Operation ein Nullbit und haben einen entsprechenden Verzweigungsbefehl, um es zu testen.
| 0
in diesem Fall die einzige Operation.
~~
genau so zu interpretieren .
Das ~
ist Bitwise NOT Operator , ~x
ist ungefähr das gleiche wie -(x+1)
. Es ist leichter zu verstehen. So:
~2; // -(2+1) ==> -3
Überlegen Sie -(x+1)
. -1
kann diese Operation ausführen, um a zu erzeugen 0
.
Mit anderen Worten, ~
wenn es mit einem Bereich von Zahlenwerten verwendet wird, wird nur für die ein falscher Wert (erzwingen false
von 0
) erzwungen-1
Eingangswert, ansonsten anderen truthy Wert.
Wie wir wissen, -1
wird dies allgemein als Sentinel-Wert bezeichnet . Es ist für viele Funktionen verwendet , die >= 0
Rückwerte für Erfolg und -1
für Versagen in C - Sprache. Welches die gleiche Regel der Rückgabewert vonindexOf()
in JavaScript.
Es ist üblich, auf diese Weise das Vorhandensein / Fehlen eines Teilstrings in einem anderen String zu überprüfen
var a = "Hello Baby";
if (a.indexOf("Ba") >= 0) {
// found it
}
if (a.indexOf("Ba") != -1) {
// found it
}
if (a.indexOf("aB") < 0) {
// not found
}
if (a.indexOf( "aB" ) == -1) {
// not found
}
Es wäre jedoch einfacher, dies ~
wie unten beschrieben durchzuführen
var a = "Hello Baby";
~a.indexOf("Ba"); // -7 -> truthy
if (~a.indexOf("Ba")) { // true
// found it
}
~a.indexOf("aB"); // 0 -> falsy
!~a.indexOf("aB"); // true
if (!~a.indexOf( "aB" )) { // true
// not found
}
-(x+1)
wenn ich es in einer if-Anweisung sehen würde. Die Tilde sagt mir genau, was sie tut, um die 0-basierte Natur von Javascript zu kompensieren. Je weniger Klammern, desto besser zum Lesen
if (a.indexOf("Ba") > -1) {// found} //true
was zwar etwas länger als die Tilde-Beispiele ist, aber erheblich weniger als die beiden von Ihnen angegebenen Beispiele und für neue Programmierer var opinion = !~-1 ? 'more' : 'less'
verständlich ist.
~indexOf(item)
kommt ziemlich oft vor und die Antworten hier sind großartig, aber vielleicht müssen einige Leute nur wissen, wie man es benutzt und die Theorie "überspringen":
if (~list.indexOf(item)) {
// item in list
} else {
// item *not* in list
}
++
und --
weil sie "übermäßige Trickserei fördern" und dennoch irgendwie ~
überlebt haben (im Schatten lauern) github.com/airbnb/javascript/issues/540
list.indexOf(item) >= 0
oder, ... > -1
da Javascript auf Null basiert und sich nicht von Anfang an dafür entschieden hat, dies zu beheben . Darüber hinaus weiß jeder, der in Javascript etwas Sinnvolles tut, nur die Meinung (wie bei Airbnb), ++
und obwohl dies --
weniger verbreitet ist, kann auf die Bedeutung geschlossen werden.
++
und --
in einer Weile wegen primitiver Methoden wie map
, forEach
usw. Mein Punkt ist , mehr darüber , warum sie nicht auch prüfen , ~
übermäßig schwierig , wenn alles , was Standard verwendet Schritt umfasst und Dekrementoperatoren. Etwas zu verbieten, damit CIS101 keinen Sinn ergibt.
Für diejenigen, die erwägen, den Tilde-Trick zu verwenden, um aus einem Ergebnis einen wahrheitsgemäßen Wert zu erstellen indexOf
, ist es expliziter und hat weniger Magie, stattdessen die includes
MethodeString
anzuwenden .
'hello world'.includes('hello') //=> true
'hello world'.includes('kittens') //=> false
Beachten Sie, dass dies ab ES 2015 eine neue Standardmethode ist, die in älteren Browsern nicht funktioniert. In Fällen, in denen dies wichtig ist, sollten Sie die Verwendung von String.prototype.includes polyfill in Betracht ziehen .
Diese Funktion ist auch für Arrays mit derselben Syntax verfügbar :
['apples', 'oranges', 'cherries'].includes('apples') //=> true
['apples', 'oranges', 'cherries'].includes('unicorns') //=> false
Hier ist die Array.prototype.includes Polyfill, wenn Sie ältere Browserunterstützung benötigen.