JavaScript'te dizeye yayınlama


184

StringJavaScript'te bir değişken yayınlamanın üç yolunu buldum .
Ben jQuery kaynak kodu bu üç seçenek aradı ve hepsi kullanımda .
Aralarında herhangi bir fark olup olmadığını bilmek istiyorum:

value.toString()
String(value)
value + ""

DEMO

Hepsi aynı çıktıyı üretir, ancak bunlardan biri diğerlerinden daha mı iyidir? Bazı karakterleri kaydetme avantajı olduğunu
söyleyebilirim + "", ama bu o kadar büyük bir avantaj değil, başka bir şey mi?


1
Bana öyle geliyor ki eğer her şey eşitse, standart toString()gidilecek yoldur.
asawyer

1
@asawyer. Ve neden böyle? Hepsi aynı çıktıyı üretip aynısını yapıyorlarsa, birini seçin ve onunla devam edin. Burada gerçekten durum buysa, bu benim görüşüm .
gdoron, Monica

1
İlk iki yöntem eşdeğer olmalıdır (standardı kontrol etmelisiniz, ancak yapıcı toString'i çağıracaktır). Üçüncüsü USUALLY aynı çıktıyı üretir, ancak çok farklı bir mekanizma içerir (hızın yanı sıra farklı çağrılar içerir, bu nedenle her nesne için beklediğiniz gibi olmayabilir).
Adriano Repetti

6
Bence toStringsemantik olarak bir nesnenin dize eşdeğerini elde etmeye çalıştığınız gerçeğini belgelemenin en açık yoludur. String(...)biraz geniş ve value + ""biraz hack. Ayrıca toString, sanırım küçük bir yan fayda olarak varsayalım, varsayılan bir özel uygulama ile geçersiz kılma yeteneği verir .
asawyer

2
@Adriano. Ama + ""jsperf göre en hızlı, bu yüzden ... sanırım başka bir şekilde yapar.
gdoron, Monica

Yanıtlar:


213

Onlar farklı davranır yok valueolduğunu null.

  • null.toString()bir hata atar - null 'toString' yöntemi çağırılamıyor
  • String(null)döndürür - "null"
  • null + ""ayrıca döndürür - "null"

Çok benzer davranış olur valueise undefined(bkz jbabey cevabını ).

Bunun dışında, dev döngülerde kullanmadığınız sürece endişelenmeye değmeyecek bir ihmal edilebilir performans farkı var.


Bu aslında ilginç bir fark. Bu yüzden henüz toString()kontrol etmediğinizde kullanmaktan kaçınmalısınız null.
Sammy

@SammyS. yazdırma nullveya undefinedekrana bir javascript hata daha arzu edilen bir davranış olup olmadığını bilmiyorum ...
Justus Romijn

@JustusRomijn: Gerçekten de. Bu arada, bu tür hataları işlemek için Seçenek türünü kullanmaya başladım.
Sammy S.

dizeyi kontrol etmek için bu döküm değişkenlerden herhangi birini typeof ile kontrol edebilirsiniz. typeof (null + '') == 'string'
Bruce Lim

4
Farklı davrandıkları başka bir durum daha var. v + ''v hem toString () hem de valueOf () yöntemlerine sahipse yanlış sonuç döndürür. Birleştirme toString () öğesini yok sayar ve valueOf () öğesini kullanır. Birleştirmenin başarısız olduğu bir sınıf örneği: github.com/processing-js/processing-js/blob/…
Mikita Belahlazau

26

Farklılıklar var, ancak muhtemelen sorunuzla ilgili değiller. Örneğin, toString prototipi tanımlanmamış değişkenlerde mevcut değildir, ancak diğer iki yöntemi kullanarak tanımlanmamış bir dizeye yayın yapabilirsiniz:

var foo;

var myString1 = String(foo); // "undefined" as a string

var myString2 = foo + ''; // "undefined" as a string

var myString3 = foo.toString(); // throws an exception

http://jsfiddle.net/f8YwA/


3
Bir değişken hiç tanımlanmamışsa, için hala bir hata alırsınız String(). Örnek: String(test);atar Uncaught ReferenceError: test is not defined, buna var test; String(test);neden olur "undefined".
Anthony

17

Aynı şekilde davranırlar, ancak toStringaynı zamanda bir sayı ikili, sekizli veya onaltılık dizeleri dönüştürmek için bir yol sağlar:

Misal:

var a = (50274).toString(16)  // "c462"
var b = (76).toString(8)      // "114"
var c = (7623).toString(36)   // "5vr"
var d = (100).toString(2)     // "1100100"

9

Bu JSPerf testine göre hızları farklıdır. Ancak, bunları büyük miktarlarda kullanmayacaksanız, herhangi biri iyi performans göstermelidir.

Tamlık için: Asawyer'in daha önce de belirttiği gibi, .toString()yöntemi de kullanabilirsiniz .


2
Bu jsperf aynı testi iki kez yaptı, ben düzenledim Ve new String()döndürür bir nesne değilString
gdoron Monica

new String()bir nesneyi döndürür evet. String()ancak, sorudaki dize döndürür.
Connell

2
Bu tamamen doğru değil. Boş bir dizesinin, sonuçlarından görebilir ve bir nesne yok gibi değil bir nesne ve boş dizesinin belirtilen aynı sonucu verir. Ayrıca, arayabileceğiniz new String(blarg)bir Stringnesne verir toString(). Chrome hata ayıklayıcımda, söz konusu fark dışında aynı tür nesnelerle etkili bir şekilde sonuç veriyorlar.
Sammy

@SammyS. Cevabınıza örnek performans sonuçları ekleyebilir misiniz? Jsperf bağlantısı şu anda kapalı ve kesinlikle önümüzdeki 5+ yıl içinde tekrar olacak.
mxmlnkn

9

Yukarıdakilerin hepsine ek olarak, tanımlanmış bir değer için aşağıdakilere dikkat edilmelidir v:

  • String(v) aramalar v.toString()
  • '' + vv.valueOf()başka bir tür yayın öncesi çağrı

Böylece şöyle bir şey yapabiliriz:

var mixin = {
  valueOf:  function () { return false },
  toString: function () { return 'true' }
};
mixin === false;  // false
mixin == false;    // true
'' + mixin;       // "false"
String(mixin)     // "true"

FF 34.0 ve Düğüm 0.10'da test edilmiştir


8

null, undefined, NaN, 0 ve false ile sorun yaşarsanız, tüm yayınlar '' (s ? s+'' : '')olarak ayarlanır.

bkz. http://jsperf.com/cast-to-string/8

not - şu anda tarayıcılar arasında önemli farklılıklar vardır.


4

Gerçek hayattan örnek: Ben parametrelerin keyfi bir sayı ile çağrılabilir bir günlük işlevi var: log("foo is {} and bar is {}", param1, param2). Bir DEBUGbayrak olarak ayarlanırsa true, parantezler belirtilen parametrelerle değiştirilir ve dize iletilir console.log(msg). Parametreler, Dizeler, Sayılar ve JSON / AJAX çağrıları tarafından döndürülebilecek her şey olabilir, hatta olabilir null.

  • arguments[i].toString()olası nulldeğerler nedeniyle bir seçenek değildir (bkz. Connell Watkins cevabı)
  • JSLint şikayet edecek arguments[i] + "". Bu, ne kullanılacağına dair bir kararı etkileyebilir veya etkilemeyebilir. Bazı insanlar JSLint'e sıkı sıkıya bağlı kalırlar.
  • Bazı tarayıcılarda, boş dizeleri birleştirmek dize işlevi veya dize yapıcı kullanmaktan biraz daha hızlıdır (Sammys S. yanıtında JSPerf testine bakın). Opera 12 ve Firefox 19'da, boş dizeleri birleştirmek çok daha hızlıdır (Firefox 19'da% 95) - veya en azından JSPerf bunu söylüyor.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.