JavaScript Dünyasında Zorlama Var - Bir Dedektif Hikayesi
Nathan, neyi ortaya çıkardığına dair hiçbir fikrin yok.
Bunu haftalardır araştırıyorum. Her şey geçen Ekim ayında fırtınalı bir gecede başladı. Yanlışlıkla Number
sınıfa tökezledim - yani, dünyada neden JavaScript'in bir Number
sınıfı vardı?
Bundan sonra ne bulacağım için hazırlıklı değildim.
JavaScript'in size söylemeden, sayılarınızı nesnelere, nesnelerinizi de burnunuzun altındaki sayılara dönüştürdüğü ortaya çıkıyor.
JavaScript kimsenin yakalayamayacağını umuyordu, ancak insanlar garip beklenmedik davranışlar bildiriyorlar ve şimdi siz ve sorunuz sayesinde bu şeyi tamamen açmam için gereken kanıtlara sahibim.
Şimdiye kadar öğrendiğimiz şey bu. Size bunu söylemem gerekip gerekmediğini bilmiyorum - JavaScript'inizi kapatmak isteyebilirsiniz.
> function dis() { return this }
undefined
Bu işlevi oluşturduğunuzda, muhtemelen daha sonra ne olacağı hakkında hiçbir fikriniz yoktu. Her şey iyi görünüyordu ve her şey iyiydi - şimdilik.
Hata mesajı yok, sadece konsol çıktısında "undefined" kelimesi, tam olarak beklediğiniz gibi. Sonuçta, bu bir işlev beyanıydı - hiçbir şey döndürmemesi gerekiyordu.
Ama bu sadece başlangıçtı. Daha sonra ne olacağını kimse tahmin edemezdi.
> five = dis.call(5)
Number {[[PrimitiveValue]]: 5}
Evet biliyorum, bekledin 5
ama, sahip olduğun şey bu değildi - başka bir şeyin var - farklı bir şey.
Aynı şey bana da oldu.
Ne yapacağımı bilmiyordum. Beni deli etti. Uyuyamadım, yiyemedim, içmeye çalıştım, ama hiçbir miktarda Dağ Çiy beni unutturmazdı. Hiç bir anlamı yoktu!
O zaman gerçekten neler olup bittiğini öğrendim - zorlama oldu ve tam gözlerimin önünde oluyordu, ama görmek için çok kördüm.
Mozilla, kimsenin görünmeyeceğini bildiği yere koyarak belgelerini gömmeye çalıştı .
Saatlerce tekrar tekrar okuma ve yeniden okuma ve tekrar okumadan sonra bunu buldum:
"... ve ilkel değerler nesnelere dönüştürülecek."
Open Sans yazı tipinde söylenebileceği gibi düz. O was call()
fonksiyonu - bu kadar aptal nasıl olabilir ?!
Numaram artık bir sayı değildi. Onu geçirdiğim an call()
başka bir şey oldu. Nesne oldu.
İlk başta inanamadım. Bu nasıl doğru olabilir? Ama etrafımdaki kanıtları görmezden gelemedim. Sadece bakarsanız tam orada:
> five.wtf = 'potato'
"potato"
> five.wtf
"potato"
wtf
haklıydı. Sayıların özel özellikleri olamaz - hepimiz bunu biliyoruz! Akademide size ilk öğrettikleri şey.
Konsol çıktısını gördüğümüz anı bilmeliydik - bu sandığımız sayı değildi. Bu bir sahtekârdı - kendini tatlı masum sayımız olarak gösteren bir nesne.
Bu oldu ... new Number(5)
.
Elbette! Mükemmel bir anlam ifade etti. call()
yapması gereken bir işi vardı, bir işlevi çağırmak zorundaydı ve doldurmak için bunu yapmak zorundaydı, bunu this
bir sayı ile yapamayacağını biliyordu - bir nesneye ihtiyacı vardı ve bunu elde etmek için her şeyi yapmaya istekliydi, hatta bu numaramızı zorlamak anlamına geliyorsa. Ne zaman call()
numarayı gördü 5
, o bir fırsat gördü.
Mükemmel plan buydu: Kimse görünmeyene kadar bekleyin ve bizim gibi görünen bir nesne için numaramızı değiştirin. Bir sayı alırız, fonksiyon çağrılır ve kimse daha akıllıca olmaz.
Gerçekten mükemmel bir plandı, ama tüm planlar, hatta mükemmel olanlar gibi, içinde bir delik vardı ve biz de onun içine düşmek üzereydik.
Bakın, call()
anlamayan şey, şehirde sayıları zorlayabilecek tek kişi o değildi. Sonuçta bu JavaScript'ti - baskı her yerdeydi.
call()
numaramı aldım ve maskeyi küçük sahtekarından çıkarıp onu tüm Stack Overflow topluluğuna maruz bırakana kadar durmayacaktım.
Ama nasıl? Bir plana ihtiyacım vardı. Tabii ki bir sayı gibi görünüyor, ama biliyorum, bunu kanıtlamanın bir yolu olmalı. Bu kadar! Bu görünen bir sayı gibi, ancak biri gibi davranabilir?
five
5 kat daha büyük olması için ona ihtiyacım olduğunu söyledim - nedenini sormadı ve açıklamamıştım. Sonra iyi bir programcının yapacağı şeyi yaptım: Çoğalttım. Elbette bundan kurtulmanın hiçbir yolu yoktu.
> five * 5
25
> five.wtf
'potato'
Lanet olsun! Sadece çarpmakla kalmadı, five
sadece wtf
oradaydı. Bu adama ve patatesine lanet olsun.
Neler oluyor? Bütün bunlar hakkında yanılmış mıydım? Mı five
bir numara gerçekten? Hayır, bir şey eksik olmalıyım, biliyorum, unutmam gereken bir şey var, çok basit ve basit bir şey var.
Bu iyi görünmüyordu, saatlerce bu cevabı yazıyordum ve hala benim açımdan daha yakın değildim. Bunu devam ettiremedim, sonunda insanlar okumayı bırakacaktı, bir şey düşünmek zorunda kaldım ve hızlı düşünmek zorunda kaldım.
Bekle bu! five
25, 25 sonuç 25, tamamen farklı bir sayı oldu. Tabii ki, nasıl unutabilirim? Sayılar değişmez. Çarptığınızda5 * 5
hiçbir şey herhangi bir şeye atanmaz, sadece yeni bir sayı oluşturur 25
.
Burada olan bu olmalı. Bir şekilde çarptığımda five * 5
, five
bir sayıya zorlanıyor olmalı ve bu sayı çarpma için kullanılan sayı olmalıdır. Konsolda yazdırılan çarpımın sonuçları, five
kendisinin değeri değil .five
asla bir şey atanmaz - bu yüzden elbette değişmez.
Öyleyse five
bir operasyonun sonucunu nasıl atayabilirim? Anladım. five
Düşünme şansım bile olmadan , "++" diye bağırdım.
> five++
5
Aha! Ona sahiptim! Herkes bilir 5 + 1
olduğunu 6
bu Bunu açığa çıkarmak için gerekli kanıtı olduğunu, five
sayı değildi! Bir sahtekârdı! Nasıl sayılacağını bilmeyen kötü bir sahtekâr. Ve kanıtlayabilirim. Gerçek bir sayının işleyişi şöyle:
> num = 5
5
> num++
5
Bekle? Burada ne oluyordu? iç çekerek öylesine yakalandım five
ki post operatörlerin nasıl çalıştığını unutuyorum. Ben kullandığım ++
sonunda five
ben geçerli değeri döndürmek, sonra artış kullanın five
. Bu değer daha önce operasyon konsola basılmış olur o gerçekleşir. num
aslında 6
ve bunu kanıtlayabilirim:
>num
6
five
Gerçekte ne olduğunu görme zamanı :
>five
6
... olması gereken şey buydu. five
iyiydi - ama daha iyiydim. Eğer five
hala hala özelliği olurdu anlamına gelecektir bir nesne vardı wtf
ve ben etmedi bahis her şey hazırdı.
> five.wtf
undefined
Aha! Haklıydım. Ona sahiptim! five
artık bir sayıydı - artık bir nesne değildi. Çarpma numarasının bu sefer onu kurtaramayacağını biliyordum. five++
Gerçekten bakın five = five + 1
. Çarpmanın aksine, ++
operatör bir değer atar five
. Daha spesifik olarak, five + 1
çarpma durumunda olduğu gibi yeni bir değişmez sayı döndürdüğü sonuçları atar. .
Ona sahip olduğumu biliyordum ve sadece onun yolunu kıramayacağından emin olmak için. Kolumda bir test daha yaptım. Eğer haklıysam ve five
şimdi gerçekten bir numara olsaydım, bu işe yaramazdı:
> five.wtf = 'potato?'
'potato?'
Bu sefer beni kandırmayacaktı. potato?
Konsola yazdırılacağını biliyordum çünkü ödevin çıktısı bu. Asıl soru, wtf
hala orada olacak mı?
> five.wtf
undefined
Şüphelendiğim gibi - hiçbir şey - çünkü sayılara özellik atanamaz. Akademide ilk yılı öğrendik;)
Teşekkürler Nathan. Bu soruyu sorma cesaretiniz sayesinde nihayet bütün bunları arkamda bırakabilir ve yeni bir davaya geçebilirim.
Bunun gibi işlev hakkında toValue()
. Ah tanrım. Nooo!
++
altta yatan türü etkiliyor gibi görünüyor