TLDR
Tür zorlama veya örtük tür dönüştürme, zayıf yazmayı etkinleştirir ve JavaScript genelinde kullanılır. Çoğu (sıkı eşitlik işlemleri önemli hariç operatörler ===ve !==) ve değer kontrol işlemleri (örn. if(value)...Bu değerlerin türleri operasyonla hemen uyumlu değilse), kendilerine verilen değerleri zorlamak olacaktır.
Bir değeri zorlamak için kullanılan kesin mekanizma, değerlendirilen ifadeye bağlıdır. Soruda toplama operatörü kullanılıyor.
Toplama operatörü ilk önce her iki işlenenin de ilkel olmasını sağlayacaktır, bu durumda bu durumda valueOfyöntemi çağırmayı içerir . toStringGeçersiz kılınan için yöntem olup, bu durumda adı verilir valueOfnesne üzerinde bir yöntem xtemel bir değeri verir.
Ardından, sorudaki işlenenlerden biri bir dizge olduğundan, her iki işlenen de dizelere dönüştürülür. Bu süreç soyut, dahili işlemi ToString(not: büyük harfle yazılmış) kullanır ve toStringnesnedeki (veya prototip zincirindeki) yöntemden farklıdır .
Son olarak, ortaya çıkan dizeler birleştirilir.
ayrıntılar
JavaScript'teki her dil türüne karşılık gelen (yani Number, BigInt, String, Boolean, Symbol ve Object) her yapıcı işlev nesnesinin prototipinde iki yöntem vardır: valueOfve toString.
Amacı, valueOfbir nesneyle ilişkili ilkel değeri (eğer varsa) geri getirmektir. Bir nesnenin altında yatan bir ilkel değer yoksa, o zaman nesne basitçe döndürülür.
Bir valueOfilkele karşı çağrılırsa, ilkel normal şekilde otomatik olarak kutuya alınır ve temel ilkel değer döndürülür. Dizeler için temel ilkel değerin (yani tarafından döndürülen değer valueOf) dize temsilinin kendisi olduğuna dikkat edin.
Aşağıdaki kod, valueOfyöntemin temel ilkel değeri bir sarmalayıcı nesnesinden döndürdüğünü ve ilkellere karşılık gelmeyen, değiştirilmemiş nesne örneklerinin döndürülecek ilkel bir değere sahip olmadığını, bu nedenle yalnızca kendilerini döndürdüklerini gösterir.
console.log(typeof new Boolean(true)) // 'object'
console.log(typeof new Boolean(true).valueOf()) // 'boolean'
console.log(({}).valueOf()) // {} (no primitive value to return)
Amacı toString, diğer taraftan, bir nesnenin dize gösterimini dönmek olduğunu.
Örneğin:
console.log({}.toString()) // '[object Object]'
console.log(new Number(1).toString()) // '1'
Çoğu işlem için JavaScript sessizce bir veya daha fazla işleneni gerekli türe dönüştürmeye çalışır. Bu davranış, JavaScript'in kullanımını kolaylaştırmak için seçildi. JavaScript başlangıçta istisnalara sahip değildi ve bu da bu tasarım kararında bir rol oynamış olabilir. Bu tür örtük tür dönüştürmeye tür zorlama denir ve JavaScript'in gevşek (zayıf) tür sisteminin temelini oluşturur. Bu davranışın arkasındaki karmaşık kuralların amacı, yazımın karmaşıklığını dilin kendisine ve kodunuzun dışına taşımaktır.
Zorlayıcı süreç sırasında, meydana gelebilecek iki dönüşüm modu vardır:
- Bir nesnenin bir ilkele dönüştürülmesi (bu, bir tür dönüşümünün kendisini içerebilir) ve
- İlkel türlerinden biri, bir yapıcı işlevi nesnesini kullanarak belirli bir tür, örneğin doğrudan dönüştürme, (yani.
Number(), Boolean(), String()Vs.)
Bir İlkele Dönüşüm
İlkel olmayan türleri, üzerinde çalışılacak ilkel türlere dönüştürmeye çalışırken, soyut işlem ToPrimitive, isteğe bağlı bir "sayı" veya "dizge" "ipucu" ile çağrılır. İpucu atlanırsa, varsayılan ipucu 'sayı'dır ( @@toPrimitiveyöntem geçersiz kılınmadıkça). İpucu 'dizge' ise, o zaman toStringönce denenir ve valueOfikinci eğer toStringbir ilkel döndürmezse. Aksi takdirde, tersi. İpucu, dönüştürmeyi talep eden işleme bağlıdır.
Toplama operatörü hiçbir ipucu vermez, bu nedenle valueOfönce denenir. Çıkarma operatörü bir 'sayı' ipucu verir, bu nedenle valueOfilk denenir. İpucunun 'dize' olduğu spesifikasyonda bulabildiğim tek durumlar şunlardır:
Object#toString
ToPropertyKeyBir bağımsız değişkeni, özellik anahtarı olarak kullanılabilecek bir değere dönüştüren soyut işlem
Doğrudan Tür Dönüştürme
Her operatörün işlemlerini tamamlamak için kendi kuralları vardır. Toplama operatörü ilk olarak ToPrimitiveher işlenenin bir ilkel olmasını sağlamak için kullanacaktır ; daha sonra, işlenenlerden biri bir dizge ise, ToStringdizelerle beklediğimiz dizge birleştirme davranışını sunmak için kasıtlı olarak her işlenen üzerinde soyut işlemi başlatır. ToPrimitiveAdımdan sonra her iki işlenen de dize değilse, aritmetik toplama gerçekleştirilir.
Toplamadan farklı olarak, çıkarma operatörü aşırı yüklenmiş davranışa sahip değildir ve bu nedenle, toNumericbunları kullanarak ilk önce onları ilkellere dönüştüren her işleneni çağıracaktır ToPrimitive.
Yani:
1 + 1 // 2
'1' + 1 // '11' Both already primitives, RHS converted to string, '1' + '1', '11'
1 + [2] // '12' [2].valueOf() returns an object, so `toString` fallback is used, 1 + String([2]), '1' + '2', 12
1 + {} // '1[object Object]' {}.valueOf() is not a primitive, so toString fallback used, String(1) + String({}), '1' + '[object Object]', '1[object Object]'
2 - {} // NaN {}.valueOf() is not a primitive, so toString fallback used => 2 - Number('[object Object]'), NaN
+'a' // NaN `ToPrimitive` passed 'number' hint), Number('a'), NaN
+'' // 0 `ToPrimitive` passed 'number' hint), Number(''), 0
+'-1' // -1 `ToPrimitive` passed 'number' hint), Number('-1'), -1
+{} // NaN `ToPrimitive` passed 'number' hint', `valueOf` returns an object, so falls back to `toString`, Number('[Object object]'), NaN
1 + 'a' // '1a' Both are primitives, one is a string, String(1) + 'a'
1 + {} // '1[object Object]' One primitive, one object, `ToPrimitive` passed no hint, meaning conversion to string will occur, one of the operands is now a string, String(1) + String({}), `1[object Object]`
[] + [] // '' Two objects, `ToPrimitive` passed no hint, String([]) + String([]), '' (empty string)
1 - 'a' // NaN Both are primitives, one is a string, `ToPrimitive` passed 'number' hint, 1-Number('a'), 1-NaN, NaN
1 - {} // NaN One primitive, one is an object, `ToPrimitive` passed 'number' hint, `valueOf` returns object, so falls back to `toString`, 1-Number([object Object]), 1-NaN, NaN
[] - [] // 0 Two objects, `ToPrimitive` passed 'number' hint => `valueOf` returns array instance, so falls back to `toString`, Number('')-Number(''), 0-0, 0
O Not Datevarsayılan geçersiz kılmak için yalnızca içsel olması ile içsel nesne, benzersiz @@toPrimitivevarsayılan ipucu (daha doğrusu 'numarası' den) 'dizge' olduğu tahmin edildiği yöntem. Buna sahip olmanın nedeni Date, programcının rahatlığı için örneklerin sayısal değerleri yerine varsayılan olarak okunabilir dizelere çevrilmesidir. @@toPrimitiveKullanarak kendi nesnelerinizde geçersiz kılabilirsiniz Symbol.toPrimitive.
Aşağıdaki ızgara, soyut eşitlik operatörü ( ==) ( kaynak ) için zorlama sonuçlarını gösterir :

Bkz ayrıca .
window.console.log (x);yaalert (x);?