it-swarm-tr.com

+ Birleştirme için neden bu kadar kötü?

Herkes JavaScript sorunlarından birinin + [ örnek ] dize birleştirme için. Bazıları sorunun +, tür zorlamadır [önceki örnekteki yorumlara bakın]. Ancak güçlü yazılan diller, birleştirme ve zorlama türleri için + işaretini sorunsuz kullanır. Örneğin, C # ile:

int number = 1;
MyObject obj = new MyObject();

var result = "Hello" + number + obj;
// is equivalent to
string result = "hello" + number.ToString() + obj.ToString();

Öyleyse neden JavaScript'te dize birleştirme bu kadar büyük bir sorun?

44
configurator

Şu JavaScript kodu parçasını düşünün:

var a = 10;
var b = 20;
console.log('result is ' + a + b);

Bu günlüğe kaydedilecek

sonuç 1020

Hangi büyük olasılıkla amaçlanan değildir ve izlemesi zor olabilir.

69
Mchl

"Kötü" dediğinde "yanlış" mı demek istiyorsun, yoksa "yavaş" mı demek istiyorsun? Dize birleştirme yapmak için matematiksel işleçleri kullanma argümanı tartışmalı olarak "yanlış" bir bağımsız değişkendir, ancak dize birleştirme işleminin _+_ işlevini kullanmanın çok çok yavaş ol.

Performanstan bahsederken _"Hello" + number_ hakkında konuşmuyoruz, tekrar tekrar bir döngüye ekleyerek nispeten büyük bir dize oluşturmaktan bahsediyoruz.

_var combined = "";
for (var i = 0; i < 1000000; i++) {
    combined = combined + "hello ";
}
_

JavaScript'te (ve bu konuda C #) dizeler değiştirilemez. Asla değiştirilemezler, sadece diğer dizelerle değiştirilebilirler. Muhtemelen _combined + "hello "_'in combined değişkenini doğrudan değiştirmediğini biliyorsunuzdur - işlem iki dizeyi birlikte birleştirmenin sonucu olan yeni bir dize oluşturur, ancak daha sonra bu yeni dizeyi atamanız gerekir değiştirilmesini istiyorsanız combined değişkenine dönüştürün.

Yani bu döngünün yaptığı bir milyon farklı dize nesnesi oluşturmak ve bunların 999,999'unu atmak. Sürekli olarak büyüyen birçok dizeyi oluşturmak hızlı değildir ve şimdi çöp toplayıcının bundan sonra temizlemek için çok işi vardır.

C #, aynı ortamda StringBuilder sınıfı tarafından çözülen sorunla aynıdır. JavaScript'te, birleştirmek istediğiniz tüm dizelerin bir dizisini oluşturarak ve daha sonra döngüde milyon kez yerine bir defada birleştirerek çok daha iyi performans elde edersiniz:

_var parts = [];
for (var i = 0; i < 1000000; i++) {
    parts.Push("hello");
}
var combined = parts.join(" ");
_
44
Joel Mueller

Yalnızca sayı ekleyebildiğiniz ve yalnızca dizeleri birleştirebildiğiniz sürece, hem ekleme hem de birleştirme için + kullanmak kötü değildir. Bununla birlikte, Javascript gerektiğinde sayılar ve dizeler arasında otomatik olarak dönüşür, bu nedenle:

3 * 5 => 15
"3" * "5" => 15
2 + " fish" => "2 fish"
"3" + "5" => "35"  // hmmm...

Belki daha basit bir şekilde, otomatik tip dönüşümü varlığında "+" aşırı yüklenmesi + operatörünün beklenen ilişkisini bozar:

("x" + 1) + 3 != "x" + (1 + 3)
14
kevin cline