Ar gali (== 1 == 2 = = 3) kada nors įvertinti tiesa?

Moderatoriaus pastaba: nepalikite noro pakeisti kodą arba ištrinti šį pranešimą. Erdvės modelis gali būti klausimo dalis, todėl neturėtų būti be reikalo suklastotas. Jei esate stovykloje „spragas - nepilnametis“, turėtumėte sugebėti priimti kodą taip, kaip yra.

Ar įmanoma, kad (a== 1 a ==2 a==3) gali įvertinti true javascript?

Tai yra interviu klausimas, kurį pateikė pagrindinė technologijų bendrovė. Tai įvyko prieš dvi savaites, bet vis dar bandau rasti atsakymą. Žinau, kad mes niekada neperrašome tokio kodo mūsų kasdieniame darbe, bet aš smalsu.

2318
15 янв. nustatė Dimpu Aravind Buddha sausio 15 d 2018-01-15 23:20 '18, 11:20 val. 2018-01-15 23:20
@ 29 atsakymai

Jei naudojate == kaip tai veikia , galite tiesiog sukurti objektą su pasirinktiniu „ toString (arba „ valueOf ), kuris keičia tai, ką jis grąžina kiekvieną kartą, kai jis naudojamas, kad jis atitiktų visas tris sąlygas.


Dėl šios priežasties darbas susijęs su laisvo lygybės operatoriaus naudojimu. Naudojant laisvą lygybę, jei vienas iš operandų skiriasi nuo kito, variklis bandys konvertuoti vieną į kitą. Jei objektas yra kairėje, o numeris dešinėje, jis bandys konvertuoti objektą į numerį, pirmą kartą skambindamas į „ valueOf jei jis yra valueOf , ir priešingu atveju jis skambins į „ toString . Tokiu atveju aš naudoju „ toString paprasčiausiai todėl, kad man atsitiko, kad „ valueOf būtų prasmingesnė. Jei vietoj to toString eilutę iš toString , tada variklis bandys konvertuoti eilutę į skaičių, suteikdamas mums tą patį galutinį rezultatą, nors ir su šiek tiek ilgesniu keliu.

3166
15 янв. Kevino B atsakymas, pateiktas sausio 15 d 2018-01-15 23:35 '18, 11:35 pm 2018-01-15 23:35

Aš negalėjau atsispirti - kiti atsakymai neabejotinai yra teisingi, bet jūs tikrai negalite praeiti šiuo kodu:

Pažymėkite „Mathias“ kintamųjų patikros patikrinimo patvirtinimą . Jei šis keistas intervalas buvo įtrauktas į jų klausimą, tikiu, kad tai yra tokio atsakymo užuomina.

Nedarykite to. Rimtai.

Redaguoti: tai įvyko man, kad (nors neleidžiama paleisti kintamojo) Nulinio pločio staliaus ir nulio pločio simbolių pavadinimai taip pat leidžiami kintamųjų pavadinimuose - žr. „ JavaScript“ obfuscation su nulinio pločio simboliais - privalumai ir trūkumai? .

Tai atrodys taip:

1954 m
16 янв. Jeff atsakymas, pateiktas sausio 16 d 2018-01-16 08:14 '18 8:14 val. 2018-01-16 08:14

TAI GALIMA!

  var i = 0; with({ get a() { return ++i; } }) { if (a !== a) console.log("yep, this is printed."); } 
584
15 янв. Atsakymą pateikė Jonas Wilms sausio 15 d 2018-01-15 23:35 '18, 11:35 pm 2018-01-15 23:35

Pavyzdys be geters arba valueOf:

450
17 янв. atsakymas pateikiamas Gruodžio 17 d. 2018-01-17 14:37 '18, 14:37 pm 2018-01-17 14:37

Jei jis pateikiamas, ar tai įmanoma (NEĮSTATINTI), jis gali paprašyti a grąžinti atsitiktinį skaičių. Būtų tiesa, jei jis nuosekliai generuotų 1, 2 ir 3.

256
16 янв. Atsakymą pateikė mmmaaa 16 sausis 2018-01-16 09:21 '18, 9:21

Jei negalite nieko daryti be reguliarių išraiškų:

valueOf , kuris vadinamas, kai objektas yra lyginamas su primityviu (pvz., Numeris).  Pagrindinis a.valueOf yra tas, kad a.valueOf kiekvieną kartą grąžina naują vertę, nes ji vadina vykdomą reguliariąja išraiška su g vėliava, o tai reiškia, kad reguliariosios frazės lastIndex bus atnaujinama kiekvieną kartą, kai randamas atitikimas.  Taigi pirmą kartą šis this.r.lastIndex == 0 jis atitinka 1 ir atnaujinimus lastIndex : this.r.lastIndex == 1 , todėl tokia reguliari išraiška atitiks 2 ir tt 

200
16 янв. Atsakyti Kos sausio 16 d 2018-01-16 22:35 '18, 10:35 pm 2018-01-16 22:35

Tai gali būti padaryta naudojant pasaulinę zoną. „ nodejs žemiau esančiame kode naudokite global o ne window .

185
15 янв. atsakymą pateikė jontro sausio 15 d 2018-01-15 23:37 '18 at 23:37 pm 2018-01-15 23:37

Tai įmanoma, jei kintamasis pasiekiamas, pavyzdžiui, 2 žiniatinklio darbuotojai, naudojant „SharedArrayBuffer“, taip pat kai kurie pagrindiniai scenarijai. Galimybė yra nedidelė, tačiau yra įmanoma, kad kodą sukompiliuojant į mašinos kodą, darbo tinklai atnaujina kintamąjį tik laiku, todėl sąlygos a==1 , a==2 ir a==3 yra įvykdytos.

Tai gali būti lenktynių būklės pavyzdys daugialypėje aplinkoje, kurią teikia interneto darbuotojai ir „SharedArrayBuffer“ „JavaScript“.

Toliau pateikiamas pagrindinis įgyvendinimas:

main.js

 // Main Thread const worker = new Worker('worker.js') const modifiers = [new Worker('modifier.js'), new Worker('modifier.js')] // Let use 2 workers const sab = new SharedArrayBuffer(1) modifiers.forEach(m => m.postMessage(sab)) worker.postMessage(sab) 

worker.js

 let array Object.defineProperty(self, 'a', { get() { return array[0] } }); addEventListener('message', ({data}) => { array = new Uint8Array(data) let count = 0 do { var res = a == 1  a == 2  a == 3 ++count } while(res == false) // just for clarity. !res is fine console.log(`It happened after ${count} iterations`) console.log('You should\'ve never seen this') }) 

modifier.js

 addEventListener('message' , ({data}) => { setInterval( () => { new Uint8Array(data)[0] = Math.floor(Math.random()*3) + 1 }) }) 

„MacBook Air“ tai įvyksta po maždaug 10 mlrd.

2019

17 янв. atsakymas duotas mehulmpt 17 jan. 2018-01-17 10:39 '18, 10:39 2018-01-17 10:39

Tai taip pat įmanoma, kai serija savireguliuojančių transliuotojų:

(Tai panaši į „jontro“ sprendimą, tačiau nereikalaujama skaitiklio kintamojo.)

143
16 янв. Atsakymą pateikė Patrick Dark sausio 16 d. 2018-01-16 14:37 '18, 14:37 pm 2018-01-16 14:37

Nematau, kad šis atsakymas jau buvo išsiųstas, taigi aš taip pat mesti jį į mišinį. Tai panaši į Jeffo atsakymą su pusiau pločio „Hangul“ erdve.

graikų Alpha , kirilica-A ir Cherokee-A , Graikijos ir Cherokee mažosios raidės yra pernelyg skiriasi nuo lotynų a : α ,  , ir todėl ne padeda su aukščiau minėtu fragmentu). 

Yra visa „Homoglyph“ atakų klasė, dažniausiai suklastotų domenų vardų (pvz., wikipediа.org (kirilicų) ir wikipedia.org (lotynų)), tačiau ji taip pat gali būti rodoma kodu; dažniausiai vadinamas kyšiu (kaip minėta komentaruose, [underhanded] klausimai nebeatitinka PPCG temos, bet dažniausiai tai buvo problemos rūšis, kai atsirado tokių dalykų). Šią svetainę naudoju, norėdamas rasti homoglyfus, naudojamus šiam atsakymui.

126
16 янв. Atsakymą pateikė Draco18s 16 sausis 2018-01-16 21:44 '18, 9:44 val. 2018-01-16 21:44

Arba, jei norite patikrinti, galite naudoti klasę ir egzempliorių.

121
16 янв. Atsakymas pateikiamas Nina Scholz 16 sausis 2018-01-16 18:11 '18, 18:11 pm 2018-01-16 18:11

„Javascript“

a == a +1

„JavaScript“ sistemoje nėra sveikų skaičių, bet tik „S“, kurie yra įdiegti kaip dvigubo tikslumo plaukiojančio taško numeriai.

Tai reiškia, kad jei numeris a yra pakankamai didelis, jis gali būti laikomas lygiu trims sveikiems skaičiams:

Integer talpyklą : 

 package stackoverflow; import java.> 
90
17 янв. Atsakymą pateikė Eric Duminil 17 sausis 2018-01-17 13:14 18 m. 14 val. 2018-01-17 13:14

Taip, tai įmanoma! 😎

„„ Javascript “

 var a = 9; if‌(a==1  a== 2  a==3) { //console.log("Yes, it is possible!😎") document.write("<h1>Yes, it is possible!😎</h1>") } //-------------------------------------------- function if‌(){return true;} 

Jei matote tik mano kodo viršų ir paleisite jį, sakote WOW, kaip?

Todėl manau, kad pakanka pasakyti „taip“, gal kas nors jums pasakė: „Nieko neįmanoma“

Trick: po to, if padariau funkciją, naudoju paslėptą simbolį, kad jo vardas būtų toks, kaip. „JavaScript“ negalime iš naujo apibrėžti raktinių žodžių, todėl esu priverstas naudoti šį metodą. Tai suklastotas, if , bet tai veikia jums šiuo atveju!


C #

Aš taip pat parašiau C # versiją (padidinus turto vertę):

 static int _a; public static int a => ++_a; public static void Main() { if(a==1  a==2  a==3) { Console.WriteLine("Yes, it is possible!😎"); } } 

Demo versija

87
21 янв. atsakymas duotas RAM 21 Jan 2018-01-21 04:59 '18, 4:59 2018-01-21 04:59

Tai yra atvirkštinė @Jeff atsakymo * versija, kurioje paslėptas simbolis (U + 115F, U + 1160 arba U + 3164) naudojamas kintamiesiems, kurie atrodo kaip 1 , 2 ir 3 .

78
18 янв. Atsakymą pateikė Salman A sausio 18 d. 2018-01-18 13:51 '18 - 01:51 pm 2018-01-18 13:51

Taisyklė numeris vienas iš interviu; niekada sakykite neįmanoma.

Nereikia paslėpti simbolių gudrybių.

72
16 янв. atsakymas duotas MonkeyZeus 16 jan. 2018-01-16 20:27 '18, 8:27 p. 2018-01-16 20:27

Sąžiningai, ar yra būdas jį įvertinti ar ne (ir, kaip parodė kiti, yra keletas būdų), atsakymas, kurį norėčiau ieškoti, kalbėdamas kaip asmuo, vykdęs šimtus interviu, būtų toks:

"Na, galbūt, taip, pagal kai kurias keistas sąlygas, kurios man neaiškios ... bet jei į ją įeisiu realiame kode, norėčiau išsiaiškinti, kaip ir kodėl jis daro tai, ką jis daro padarė, ir tada iš karto pataisė kodą, kad būtų išvengta šios padėties ... bet dar svarbiau: aš niekuomet nepirašysiu šio kodo pirmiausia, nes tai yra minimalizuoto kodo apibrėžimas, ir aš bandau niekada nesukurti sudėtingo kodo. "

Manau, kad kai kurie respondentai buvo įžeidžiami dėl to, ką akivaizdžiai sukėlė labai sunkus klausimas, bet aš ne prieš kūrėjus, kurie turi nuomonę, ypač kai jie gali tai paremti svarstymais ir mano klausimas gali būti susitarta prasmingu pareiškimu apie save.

66
17 янв. atsakymą pateikė Frank W. Zammetti sausio 17 d. 2018-01-17 00:57 '18 prie 0:57 2018-01-17 00:57

Čia yra dar viena parinktis, naudojant masyvą, norint ištrinti norimas vertes.

41
16 янв. atsakymą pateikė Theophile Jan 16 2018-01-16 23:00 '18 23:00 2018-01-16 23:00

Jei kada nors klausiate tokio pokalbio klausimo (arba žiūrėkite, kokio elgesio jūsų kode yra vienodai netikėta), pagalvokite, ką gali sukelti elgesys, kuris iš pirmo žvilgsnio atrodo neįmanomas:

  1. Kodavimas : šiuo atveju kintamasis, kurį žiūrite, nėra tas, kurį manote. Tai gali atsitikti, jei jūs sąmoningai netvarkote „Unicode“, naudodami homoglifus arba tarpus , kad kintamojo pavadinimas atrodytų kaip kitas, bet kodavimo problemos taip pat gali būti įvestos atsitiktine tvarka, pavyzdžiui, kopijuojant ir įklijuojant kodą iš interneto, kuriame yra netikėtas „Unicode“ kodas ( pavyzdžiui, dėl to, kad turinio valdymo sistema atliko tam tikrą „automatinį formatavimą“, pvz., pakeitus „ fl “ „Unicode“ „LATIN SMALL LIGATURE FL“ (U + FB02)).

  2. Rasės sąlygos : gali pasireikšti lenktynių būklė , ty situacija, kai kodas nevykdomas pagal užsakovo tikėtiną seką. Rasės sąlygos dažnai būna daugiakrypčiai, tačiau kelios temos nėra būtina sąlyga lenktynėms. Asynchronija yra pakankama (ir nejaučiama, asinchronija nereiškia, kad po gobtuvu naudojami keli siūlai ).

    Atkreipkite dėmesį, kad todėl „JavaScript“ taip pat nėra laisva nuo lenktynių sąlygų tik todėl, kad ji yra viena sriegė. Žr. Čia yra paprastas, vienas sriegis, bet asinchroninis pavyzdys. Vieno pareiškimo kontekste rasės būklė būtų gana sunku patekti į javascript.

    „JavaScript“ su žiniatinklio darbuotojais yra šiek tiek kitoks, nes jūs galite turėti keletą sričių. @mehulmpt parodė mums puikų įrodymą, kad naudojatės žiniatinklio darbuotojais .

  3. Šalutinis poveikis : šalutinis poveikis lygiateisiškumo lyginimo operacijai (kuri neturėtų būti toks akivaizdus, ​​kaip ir čia pateikti pavyzdžiai, dažnai yra tai, kad šalutinis poveikis yra labai subtilus).

Šie klausimai gali pasirodyti daugelyje programavimo kalbų, o ne tik „JavaScript“, todėl čia nematome vieno iš klasikinių „ JavaScript“ WTF 1.

Žinoma, interviu klausimas ir pavyzdžiai čia atrodo labai toli. Tačiau jie yra geras priminimas, kad:

  • Šalutinis poveikis gali tapti tikrai nemalonus ir kad gerai suplanuota programa neturėtų turėti nepageidaujamų šalutinių poveikių.
  • Daugialypė ir kintanti būsena gali būti problemiška.
  • Neteisingas simbolių kodavimas ir teisingas eilių tvarkymas gali sukelti nemalonių klaidų.

1 Pavyzdžiui, galite rasti pavyzdį visiškai skirtingoje programavimo kalba (C #), kurioje yra šalutinis poveikis (akivaizdus) čia .

35
17 янв. Atsakymą pateikė Dirk Vollmar 17 jan. 2018-01-17 15:57 '18, 15:57 2018-01-17 15:57

Na, dar vienas hack su generatoriais:

31
17 янв. atsakymas duotas BaggersIO 17 sausio. 2018-01-17 00:33 '18 prie 0:33 2018-01-17 00:33

Tiesą sakant, atsakymas į pirmąją klausimo dalį yra „Taip“ kiekvienoje programavimo kalba. Pavyzdžiui, tai taikoma C / C ++:

 #define a (b++) int b = 1; if (a ==1  a== 2  a==3) { std::cout << "Yes, it possible!" << std::endl; } else { std::cout << "it impossible!" << std::endl; } 
27
16 янв. Gustavo Rodríguez atsakė į sausio 16 d 2018-01-16 22:56 '18, 10:56 val. 2018-01-16 22:56

Tas pats, bet skirtingas, bet dar vienas (gali būti „išbandytas“ kelis kartus):

26
17 янв. atsakymas pateikiamas Preda7or sausio 17 d 2018-01-17 17:18 '18, 17:18, 2018-01-17 17:18

Naudojant tarpinį serverį :

 var a = new Proxy({ i: 0 }, { get: (target, name) => name === Symbol.toPrimitive ? () => ++target.i : target[name], }); console.log(a == 1  a == 2  a == 3); 

Iš esmės prokurai tvirtina, kad yra tikslinis objektas (pirmasis parametras). „Gauti turtą“ veiksmas vadinamas, kai == verčia jo tipą lyginti jį su kiekvienu numeriu. Taip atsitinka:

  • Kuriame tikslinį objektą { i: 0 } , kur turtas i yra mūsų skaitiklis
  • Mes sukuriame taikinio proxy ir priskiriame jį
  • Palyginimui, a == tipo a priverstas primityvia verte.
  • Šio tipo prievarta paskambina a[Symbol.toPrimitive]() viduje
  • a[Symbol.toPrimitive] funkcijos įsigijimą naudojant „get handler“
  • Symbol.toPrimitive serveris "get handler" patikrina, ar gautas ++target.i . Jei bus atkurta kita nuosavybė, mes tiesiog grįžtame į numatytojo turto vertės, target[name] grąžinimą

Taigi:

 var a = ...; // a.valueOf == target.i == 0 a == 1  // a == ++target.i == 1 a == 2  // a == ++target.i == 2 a == 3 // a == ++target.i == 3 

Как и в большинстве других @, это работает только со свободной проверкой равенства ( == ), так как проверка строгого равенства ( === ) не вызывает тип принуждения, которое Proxy может перехватить.

26
ответ дан IceCreamYou 20 янв. '18 в 1:19 2018-01-20 01:19