if (x == false) vs. if (x = 'false')

Permalänk
Avstängd

if (x == false) vs. if (x = 'false')

Jag provar mig fram att utvärdera en variabel i en if sats och finner att två olika sätt att skriva ger samma resultat.

if (x == false) { // Gör nåt }

gör samma sak som

if (x = 'false') { // Gör nåt }

Är det helt likvärdiga sätt att skriva eller skulle det kunna ge olika resultat under andra omständigheter?

Permalänk
Hedersmedlem

Och vilket språk är detta?
Funkar det både om du sätter både x till false och true innan if-satsen? Jag skulle tro att det är skillnad. Rent generellt är = en tilldelning och == en jämförelse i de flesta språk. Dvs i ditt andra kodexempel så har x värdet 'false' efter din kod har körts. I Javascript finns även === för att göra en jämförelse.

Visa signatur

Använd gilla för att markera nyttiga inlägg!

Permalänk
Avstängd

@giplet:
Sorry. Det är javascript. Jag kör en utvärdering av variabel is_android:

var nua = navigator.userAgent; var is_android = ((nua.indexOf('Mozilla/5.0') > -1 && nua.indexOf('Android ') > -1 && nua.indexOf('AppleWebKit') > -1) && !(nua.indexOf('Chrome') > -1));

Jag får samma resultat med if (is_android == false)... som med if (is_android = 'false')...

EDIT: så false är både ett värde och en sträng i det här fallet?

Permalänk
Hedersmedlem

Om x i sig är en boolean så är det onödigt att jämföra med false överhuvudtaget:

if (!x) { // Gör nåt }

kommer "göra något" om x räknas som falsk (är det en boolean så är det lätt; i andra fall så behöver man läsa in sig lite på språket i fråga för att veta vad som händer; se föregående länk). Generellt så utför man bara onödigt extraarbete om man jämför något med en boolean.

Visa signatur

Nu med kortare användarnamn, men fortfarande bedövande långa inlägg.

Permalänk
Medlem
Skrivet av pigge_85:

Jag provar mig fram att utvärdera en variabel i en if sats och finner att två olika sätt att skriva ger samma resultat.

if (x == false) { // Gör nåt }

gör samma sak som

if (x = 'false') { // Gör nåt }

Är det helt likvärdiga sätt att skriva eller skulle det kunna ge olika resultat under andra omständigheter?

x = 'false' är en tilldeldning, inte en jämförelse, och eftersom 'false' är ett "giltigt värde" (eller vad man ska kalla det, dvs det är inte 0, undefined eller en tom sträng) så kommer javascript i praktiken tolka det som true, och koden du har i if-blocket kommer att exekveras.

Men det blir ordentligt fel: du kan lika gärna skriva if (true) i ditt fall, för koden i if-blocket kommer alltid att köras. Dessutom får du följdfelet att x får värdet 'false', vilket knappast är önskvärt.

Det där är ett vanligt misstag i alla språk som inte kräver att värdet som if kontrollerar är en boolean. I språk som Java och C# är det inte tillåtet, och kompilatorn totalvägrar, vilket är bra.

Visa signatur

5950X, 3090

Permalänk
Medlem

@phz: Jag håller med, men lustigt nog har jag ofta sett rekommendationer att inte använda !, för att det anses mer svårläst/svårtolkat.

Visa signatur

5950X, 3090

Permalänk
Medlem
Skrivet av pigge_85:

@giplet:
Sorry. Det är javascript. Jag kör en utvärdering av variabel is_android:

var nua = navigator.userAgent; var is_android = ((nua.indexOf('Mozilla/5.0') > -1 && nua.indexOf('Android ') > -1 && nua.indexOf('AppleWebKit') > -1) && !(nua.indexOf('Chrome') > -1));

Jag får samma resultat med if (is_android == false)... som med if (is_android = 'false')...

EDIT: så false är både ett värde och en sträng i det här fallet?

Det är en enorm skillnad på ett, två eller tre likamedtecken. = används för tilldelning, medan == och === används för jämförelse exkl. respektive inkl. jämförelse av datatypen.

Allt du skriver inom enkla eller dubbla ctitationstecken blir strängar, dvs. 'false' och "false" är strängar och false är ett booleskt värde.

Permalänk
Skrivet av backfeed:

Det där är ett vanligt misstag i alla språk som inte kräver att värdet som if kontrollerar är en boolean. I språk som Java och C# är det inte tillåtet, och kompilatorn totalvägrar, vilket är bra.

Där av tumregeln att man alltid ska använda "===" i javascript. Då måste även typerna stämma överens.
1 == true
true
1 === true
false

Permalänk
Hedersmedlem

(Hade redan börjat skriva, så postar även om det dykt upp svar under tiden.)

Skrivet av pigge_85:

Jag får samma resultat med if (is_android == false)... som med if (is_android = 'false')...

Nej, det får du inte.

  • if (is_android == false) kommer köra if-satsen om is_android är "falsk" (men använd hellre if (!is_android) som nämndes ovan).

  • if (is_android = 'false') kommer köra if-satsen om det värde som returneras av uttrycket inom parantesen är sant; värdet som returneras av ett tilldelningsuttryck är i JavaScript det värde som tilldelats, så detta uttryck kommer:

    1. sätta is_android till strängen 'false' (OBS: inte det booleanska värdet false)

    2. testa om strängen 'false' evaluerar till något "sant" i ett villkorsuttryck.

    Testar vi själva, eller om vi tittar i en trevligt tillgänglig referensdokumentation så ser vi att:

    Citat:

    Any value that is not undefined, null, 0, NaN, or the empty string (""), and any object, including a Boolean object whose value is false, evaluates to true when passed to a conditional statement.

    vilket gör att strängen 'false' kommer evalueras som "sann" när den används i ett villkorsuttryck, och alltså kommer if-satsen alltid köras, samtidigt som variabeln is_android alltid skrivs över.

Skrivet av pigge_85:

EDIT: så false är både ett värde och en sträng i det här fallet?

false är en (inbyggd "primitiv") boolean, 'false' är en sträng. Strängar (och alla andra objekt) kan dock evaluera till "sant" eller "falskt" beroende på inehåll och kontext enligt olika regler, som inte minst i fallet JavaScript kan överraska en oförsiktig programmerare. Jag citerade en regel ovan, länkade en sida med mer information i ett tidigare inlägg, och man kan även titta på denna roliga tabell för att se hur dessa evalueringar sker.

Visa signatur

Nu med kortare användarnamn, men fortfarande bedövande långa inlägg.

Permalänk
Medlem

Det här är anledningen till att folk inte ska använda Javascript för att lära sig programmera. Det är inte ditt fel OP utan det är språket som är så jävla sämst.

Visa signatur

AW3423DW QD-OLED - Ryzen 5800x - MSI Gaming Trio X 3090 - 64GB 3600@cl16 - Samsung 980 Pro 2TB/WD Black SN850 2TB

Permalänk
Medlem
Skrivet av Yxskaftet:

Där av tumregeln att man alltid ska använda "===" i javascript. Då måste även typerna stämma överens.
1 == true
true
1 === true
false

Precis. Det är inte bara en gång jag hittat fel i javascript orsakade av att === inte använts.

Visa signatur

5950X, 3090

Permalänk
Avstängd

Attans! Tänk vad jag var ute och cyklade där. Tack alla för mycket bra förklaringar!

Skrivet av phz:

man kan även titta på denna roliga tabell för att se hur dessa evalueringar sker.

Jag tror jag ska skriva ut den där matrisen och sätta upp bredvid monitorn som en påminnelse.

Permalänk
Hedersmedlem
Skrivet av backfeed:

@phz: Jag håller med, men lustigt nog har jag ofta sett rekommendationer att inte använda !, för att det anses mer svårläst/svårtolkat.

Ja, vad som är svårläst eller ej är en filosofisk fråga . I detta fall så är det till och med så lurigt att if (x == false) och if (!x) (och för den delen if (x === false)) inte beter sig på exakt samma sätt, visat i exempelvis den värdetabell som jag länkade ovan.

Personligen så ser jag generellt "lättläst" som ett uttryck för att kod är skriven på ett sätt som man kan förvänta sig i det givna språket, vilket inkluderar att använda språkets "best practices". Eftersom JavaScript har !-operatorn så skulle jag inte förvånas av att se den; snarare skulle jag fundera på varför den inte användes om jag såg en jämförelse med false.

Lägger man därtill att man i det närmaste bör kunna utgå ifrån att den som läser har någon form av syntaxuppmärkning i sin editor så låter argument som "svårläst" mest som argument i stil med "jag har inte riktigt lärt mig detta mer uppenbara sätt än, så jag är inte van vid att se det". Jag håller med dig (som höll med mig ) om att man bör använda ! där det är tänkt att vara applicerbart.

Det blir lite grumligare vatten när man ser personer använda exempelvis !!x som en "genväg" för att kasta x till en boolean enligt JavaScripts "truthy"/"falsy"-regler; i någon mån så förstår man vad som händer efter att ha sett det någon gång, men hade jag sett det i kod så hade jag tänkt både en och två gånger på hur situationen hade kunnat uppstå där en programmerare tänkte "detta är en bra lösning!" och sedan skrev så. Jag har sett personer som hävdat att det gör det tydligare att man medvetet använder en icke-boolean xsom en boolean om man skriver !!x, men jag känner mig inte övertygad .

Visa signatur

Nu med kortare användarnamn, men fortfarande bedövande långa inlägg.

Permalänk
Skrivet av celoz:

Det här är anledningen till att folk inte ska använda Javascript för att lära sig programmera. Det är inte ditt fel OP utan det är språket som är så jävla sämst.

- Sa ingen som är bra på JavaScript någonsin

Finns självklart brister, precis som i alla andra språk. Men det har också lika många fördelar.

Permalänk
Medlem
Skrivet av celoz:

Det här är anledningen till att folk inte ska använda Javascript för att lära sig programmera. Det är inte ditt fel OP utan det är språket som är så jävla sämst.

Skrivet av Yxskaftet:

- Sa ingen som är bra på JavaScript någonsin

Finns självklart brister, precis som i alla andra språk. Men det har också lika många fördelar.

Skriver mycket hellre JavaScript än t ex PHP: där har vi ett riktigt dåligt språk! (och standardbibliotek)

Visa signatur

Kom-pa-TI-bilitet

Permalänk
Avstängd
Skrivet av phz:

Om x i sig är en boolean så är det onödigt att jämföra med false överhuvudtaget:

if (!x) { // Gör nåt }

kommer "göra något" om x räknas som falsk (är det en boolean så är det lätt; i andra fall så behöver man läsa in sig lite på språket i fråga för att veta vad som händer; se föregående länk). Generellt så utför man bara onödigt extraarbete om man jämför något med en boolean.

Jag håller med dig om att ! operatorn är bättre, men framför allt tycker jag att man ska försöka ha variabler som betyder något när de är sanna så man inte behöver använda ! eller === false tex

if(this.canSave) { }

istället för tex

if(!this.invalid) { }

P.S vad har hänt med knappen för att code-formatera text?

edit: Och sedan kan man när man ändå håller på att köra conventions som att funktionen save har en bool canSave. Nästa steg är att använda ett konventionramverk, som detta som jag skrivit http://jsfiddle.net/w2yd5nvp/

Visa signatur
Permalänk
Hedersmedlem
Skrivet av CyberVillain:

Jag håller med dig om att ! operatorn är bättre, men framför allt tycker jag att man ska försöka ha variabler som betyder något när de är sanna så man inte behöver använda ! eller === false tex

if(this.canSave) { }

istället för tex

if(!this.invalid) { }

Det är inte alltid man vill gå in i en sats bara för att en variabel är "sann", så man klarar sig inte utan ! bara genom att undvika "negativt döpta" variabler (invalid, incomplete, etc. — sedan finns också exempel på gränsfall: är empty positivt eller negativt uttryckt?)), om man inte förespråkar att skriva saker som:

if (valid) { } else { // Gör något } // …men nog är det lättare att skriva/läsa: if (!valid) { // Gör något }

Eller du menar kanske att man i detta fall skulle låtit variabeln heta invalid (och tilldelats värde därefter) så att man hela tiden uttrycker det "positiva" villkor för den förgrening man önskar? Även då kan man tänka sig situationer då man skulle vilja testa sanningshalten åt ena hållet en gång och sedan åt andra hållet en annan gång. Dessutom kommer man aldrig ifrån inbyggda/externa funktioner som levererar en boolean där man inte själv nödvändigen har kontroll på definitionen, så ! är nog oundvikbar.

Som sidonotis så har Python löst det på ett rätt trevligt sätt med nyckelordet not, så att man skulle skriva:

if not valid: # Gör något

där ingen borde ha problem med tydligheten, kan tyckas .

Visa signatur

Nu med kortare användarnamn, men fortfarande bedövande långa inlägg.

Permalänk
Avstängd

Nej jag menar att ofta kan utvecklaren döpa variabeln så det blir onödigt med en ! tex mitt exempel !invalid där man istället kunde döpt den till canSave (Eller vad nu som sker i if-satsen). Sedan finns det ju såklart undantag när man måste köra med !. Det som är bra med att tänka till på variabelnamn är att man ofta upptäcker andra tankevurpor då

edit: Frågan gällde ju javascript och jag antar inte det menas node och då går det ju ofta att ta bort if-satsen helt via UI-ramverket, tex mitt exemepel ovan http://jsfiddle.net/w2yd5nvp/
Jag håller precis på med en Angular site, jag är expert på Knockout så man känner sig lite handikappad, men det första jag irriterade mig på var att de bara har en disabled-binding och inte även en enabled-binding (Jag hade hellre haft en enabled om jag måste välja). Jag tycker det oftare man vill testa mot true än false

Visa signatur
Permalänk

Känns som att det är ett bra tillfälle att posta detta: https://www.destroyallsoftware.com/talks/wat