Wat doet een tilde als deze voorafgaat aan een uitdrukking?

Ik zag het in een antwoord, en ik heb het nog nooit eerder gezien.

Wat betekent het?


Antwoord 1, autoriteit 100%

~is een bitsgewijze operatordie alle bits in zijn operand omdraait.

Als uw nummer bijvoorbeeld 1was, is de binaire weergave van de IEEE 754 float(hoe JavaScript met getallen omgaat) zou zijn…

0011 1111 1111 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000

Dus ~converteert zijn operand naar een 32-bits geheel getal (bitsgewijze operators in JavaScript doen dat)…

0000 0000 0000 0000 0000 0000 0000 0001

Als het een negatief getal was, zou het worden opgeslagen in het complement van 2: keer alle bits om en voeg 1 toe.

…en draait dan alle stukjes om…

1111 1111 1111 1111 1111 1111 1111 1110

Dus wat is het nut ervan? Wanneer zou iemand het ooit kunnen gebruiken?

Het heeft nogal wat toepassingen. Als je low-level dingen schrijft, is dat handig. Als u uw toepassing heeft geprofileerd en een knelpunt heeft gevonden, kan deze efficiënter worden gemaakt door bitsgewijze trucs te gebruiken (als een mogelijketool in een veel grotere tas).

Het is ook een (algemeen) onduidelijke trucom de gevonden-retourwaarde van indexOf()in waarheid(terwijl niet gevondenals falsywordt gemaakt) en mensen gebruiken het vaak vanwege het neveneffect van het afkappen van getallen tot 32 bits (en het laten vallen van de decimale plaats door het te verdubbelen, in feite de hetzelfde als Math.floor()voor positieve getallen).

Ik zeg onduidelijkomdat het niet meteen duidelijk is waarvoor het wordt gebruikt. Over het algemeen wilt u dat uw code duidelijk communiceert met andere mensen die deze lezen. Hoewel het gebruik van ~er cool uitziet, is het over het algemeen te slim voor zijn eigen bestwil. 🙂

Het is ook minder relevant nu JavaScript heeft Array.prototype.includes()en String.prototype.includes(). Deze retourneren een booleaanse waarde. Als uw doelplatform(en) dit ondersteunen, zou u hier de voorkeur aan moeten geven om te testen op het bestaan ​​van een waarde in een string of array.


Antwoord 2, autoriteit 43%

Als u het vóór een indexOf()-expressie gebruikt, krijgt u in feite een waarheidsgetrouw/onwaarachtig resultaat in plaats van de numerieke index die direct wordt geretourneerd.

Als de retourwaarde -1is, dan is ~-10omdat -1een string van alle 1 bits. Elke waarde groter dan of gelijk aan nul geeft een resultaat dat niet nul is. Dus,

if (~someString.indexOf(something)) {
}

zal ervoor zorgen dat de code ifwordt uitgevoerd wanneer “iets” in “someString” staat. Als je .indexOf()rechtstreeks als een boolean probeert te gebruiken, zal dat niet werken omdat het soms nul retourneert (wanneer “iets” aan het begin van de tekenreeks staat).

Natuurlijk werkt dit ook:

if (someString.indexOf(something) >= 0) {
}

en het is aanzienlijk minder mysterieus.

Soms zie je dit ook:

var i = ~~something;

De operator ~tweemaal op die manier gebruiken is een snelle manier om een ​​string om te zetten in een 32-bits geheel getal. De eerste ~doet de conversie, en de tweede ~draait de bits terug. Als de operator wordt toegepast op iets dat niet in een getal kan worden omgezet, krijg je natuurlijk NaNals resultaat. (edit— eigenlijk is het de tweede ~die als eerste wordt toegepast, maar je snapt het idee.)


Antwoord 3, autoriteit 12%

De ~is Bitwise NOT Operator, ~xis ongeveer hetzelfde als -(x+1). Het is makkelijker te begrijpen, soort van. Dus:

~2;    // -(2+1) ==> -3

Overweeg -(x+1). -1kan die bewerking uitvoeren om een ​​0te produceren.

Met andere woorden, ~gebruikt met een reeks getalwaarden zal alleen een valse (dwing tot falsevan 0) waarde produceren voor de -1invoerwaarde, anders een andere waarheidswaarde.

Zoals we weten, wordt -1gewoonlijk een schildwachtwaardegenoemd. Het wordt gebruikt voor veel functies die >= 0-waarden retourneren voor succesen -1voor mislukkingin C taal. Die dezelfde regel van retourwaarde van indexOf()in JavaScript.

Het is gebruikelijk om op deze manier de aanwezigheid/afwezigheid van een substring in een andere string te controleren

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
}

Het zou echter gemakkelijker zijn om het te doen via ~zoals hieronder

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
}

Je kent JS niet: typen & Grammatica door Kyle Simpson


Antwoord 4, autoriteit 9%

~indexOf(item)komt vrij vaak voor, en de antwoorden hier zijn geweldig, maar misschien moeten sommige mensen gewoon weten hoe ze het moeten gebruiken en de theorie “overslaan”:

  if (~list.indexOf(item)) {
     // item in list
   } else {
     // item *not* in list
   }

Antwoord 5, autoriteit 4%

Voor degenen die overwegen de tilde-truc te gebruiken om een ​​truthy-waarde te maken van een indexOf-resultaat, het is explicieter en heeft minder magie om in plaats daarvan de includesmethode op String.

'hello world'.includes('hello') //=> true
'hello world'.includes('kittens') //=> false

Houd er rekening mee dat dit een nieuwe standaardmethode is vanaf ES 2015, dus het werkt niet in oudere browsers. Als dat van belang is, kunt u overwegen de String.prototype.includes polyfillte gebruiken.

Deze functie is ook beschikbaar voor arrays die de dezelfde syntaxis:

['apples', 'oranges', 'cherries'].includes('apples') //=> true
['apples', 'oranges', 'cherries'].includes('unicorns') //=> false

Hier is de Array.prototype.includes polyfillals je ondersteuning voor oudere browsers nodig hebt.

Other episodes