JavaScript'te bir sayıyı dizeye dönüştürmenin en iyi yolu nedir?


Yanıtlar:


516

bunun gibi:

var foo = 45;
var bar = '' + foo;

Aslında, bunu basit bir rahatlık için tipik olarak böyle yapmama rağmen, ham hız için 1000'den fazla tekrarlama için bir avantaj var..toString()

Performans testlerini burada görebilirsiniz (benim tarafımdan değil, kendi yazımı yazdığımda buldum): http://jsben.ch/#/ghQYR

En hızlı yukarıdaki JSPerf testine dayanmaktadır: str = num.toString();

Dönüşümü 0.1 saniyede 1 Milyon kez herhangi bir şekilde yapabileceğinizi düşündüğünüzde hız farkının aşırı derecede önemli olmadığı belirtilmelidir .

Güncelleme: Hız, tarayıcıya göre çok farklı görünüyor. Chrome'da num + ''bu teste göre en hızlı görünüyor http://jsben.ch/#/ghQYR

Güncelleme 2: Yine yukarıdaki testime dayanarak, Firefox 20.0.1'in örnekten .toString()yaklaşık 100 kat daha yavaş yürütüldüğüne dikkat edilmelidir '' + num.


58
Dönüşümün tercih edilen bir cevabı veremeyeceği durumlar vardır: '' + 123e-50iadeler "1.23e-48".
hongymagic

21
@hongymagic: bu cevap aslında akla gelebilecek tek şeydir: sayı, nasıl girildiğini ummuyor ya da bilmiyor ve standart basılı gösterim noktadan önce tam bir rakam.
Svante

4
Testi bana farklı bir sonuç gösterdiğinde jsben.ch/ghQYR'de çalıştırdım !
Maryam Saeidi

2
Bu yanıtı seviyorum çünkü null foobir hata atmıyor.
17:41, ttugates

2
@MaryamSaeidi: kullanma drublic s' jsperf.com testi yukarıda daha tutarlı görünüyor.
Giraldi

364

Bence n.toString()ödülü netleştirmek için alıyor ve fazladan yük taşıdığını düşünmüyorum.


Son tarayıcı sürümlerinde önemsiz olmasına rağmen bazı ek yükler taşır. Firefox
Quantum'da

11
Bu güvensiz. n boş veya tanımsız olabilir.
david.pfx

20
@ david.pfx soru, sayısal değerlerin bir dizeye nasıl dönüştürüleceğini sorar. Bu cevapla çalışmayan sayısal olmayan değerlere (örn null. undefined) Örnek vermek, onu "güvensiz" kılar.
Michael Martin-Smucker

5
@ MichaelMartin-Smucker: Çok fazla JS yazarsanız, işlerin nadiren çok kesildiğini ve kurutulduğunu anlarsınız. Soru açıktı ve IMO iyi bir cevap en azından aslında boş veya tanımsız bir dize konusunu kabul etmelidir. YMMV.
david.pfx

@ david.pfx Bir sürü js yazdım ve bir dize olarak bir sayı ve dize olarak bir sayı dışında bir şey yeterli olurdu son kez hatırlamıyorum. Bu doğru cevap. Elleçlemeye cevap yoktur nullveya undefineduygulamaya özel olduğu için, (n || defaultNumber).toString() çoğu insanın böyle bir durumda ne isteyeceğini hayal ederken , tüm sorulara çalışmamız gerektiğini kesinlikle kabul etmiyorum. Bu, sayıları dizelere, iyi mimariyi ve gerektiğinde ayrı dersler olan diğer tür dönüşümleri dönüştürmeyle ilgili idi.
George Reith

73

Açık dönüşümler, dilde yeni olan birine çok açıktır. Diğerlerinin de belirttiği gibi, tip zorlamayı kullanmak, bir geliştirici zorlama kurallarının farkında değilse belirsizliğe yol açar. Nihayetinde geliştirici süresi CPU zamanından daha pahalıdır, bu yüzden ikincisi için ikincisinin maliyetini optimize ederim. Olduğu söyleniyor, bu durumda fark muhtemelen ihmal edilebilir, ama eğer emin değilim bu tür bir şey optimize edecek bazı iyi JavaScript kompresörleri vardır.

Yani, yukarıdaki nedenlerden dolayı: n.toString()veya String(n). null veya undefined ise String(n)başarısız olmayacak çünkü muhtemelen daha iyi bir seçimdir n.


12
Soru, sayıları dönüştürmeyle ilgili, sayıları dönüştürmeyle ilgili değil null, veya undefined. Eğer nbir nullveya undefineddolayı benim programda bir hatadan sonra benim programı bana bulma ve hata düzeltme daha iyi bir şans vermek için, bu durumda başarısız tercih ederim. Program çöküyor onun hataları bulmak yardımcı olmak için, programcı için hediyeler :-). Alternatif olarak, tasarlandığı gibi çalışmayan, böcekler üzerinde dikkatlice parlatılan yazılımlar sunmaktır. Yani, String(n)bir hatayı maskelemek için kullanmaktan hoşlanmıyorum.
Matt Wallis

1
String(n)işlevsel bir tarzda, örneğin alt çizgi birleştirmesiyle kullanmak için iyidir _.compose(funcThatNeedsAStringParam, String).
Rik Martins

2
Dize (null) programın çökmesine neden olmaz, ancak "null" değişmez dizesini döndürür. Veriler yasal olarak boş olabilirse, verileri açıkça ele almanız gerekir.
Peter Smartt

1
@MattWallis Bence bu cevap verenin değil, geliştiricinin kararı olmalı, değil mi?
forresthopkinsa

30

... JavaScript'in ayrıştırıcısı bir sayıdaki nokta gösterimini kayan nokta değişmezi olarak ayrıştırmaya çalışır.

2..toString(); // the second point is correctly recognized
2 .toString(); // note the space left to the dot
(2).toString(); // 2 is evaluated first

Kaynak


17

Yanaktaki dil açıkça:

var harshNum = 108;
"".split.call(harshNum,"").join("");

Veya ES6'da şablon dizelerini kullanabilirsiniz :

var harshNum = 108;
`${harshNum}`;

Testleri ES6 şablonlarıyla çalıştırırsam, bazen '' + numberyöntemden daha hızlı olduğu bile kanıtlanabilir . Bununla birlikte, bu kriterlerin sonuçları, birden fazla kez gerçekleştirilirken çok değişmektedir, bu yüzden çok ciddiye alınması gerekip gerekmediğinden emin değilsiniz.
Nico Van Belle

15

Diğer cevaplar zaten diğer seçenekleri kapsıyordu, ancak bunu tercih ediyorum:

s = `${n}`

Kısa, özlü, diğer birçok yerde zaten kullanılıyor (modern bir çerçeve / ES sürümü kullanıyorsanız), bu nedenle herhangi bir programcının anlayacağı güvenli bir bahis.

(Genellikle) çok önemli olduğu için değil, aynı zamanda diğer yöntemlere kıyasla en hızlılardan biri gibi görünüyor .


N bir sayı olmasa da güvenlidir.
david.pfx

Ama öyleyse öyle n.toString()değil mi?
amn

1
@amn eğer nolduğunu undefinedo kullanarak bir yazım hatası atar.toString()
Jee Mok

Bu String(n)her durumda olduğu gibi aynı sonucu vermez mi? Tek fark, daha az net olmasıdır.
Bennett McElwee

Ve çok daha yavaş.
Adrian Bartholomew

12

Herhangi bir değişkeni bir dizeye dönüştürmenin en basit yolu, bu değişkene boş bir dize eklemektir.

5.41 + ''    // Result: the string '5.41'
Math.PI + '' // Result: the string '3.141592653589793'

2
(5.41 + '').substring()
Parens

Bunun neden not edilmesi gerekiyor?
Adrian Bartholomew

7

Eğer gerekiyorsa biçimlendirmek belirli sonucu , ondalık basamak sayısı para birimini temsil etmek, örneğin, aşağıdaki gibi bir şey gerekiyor toFixed()yöntemle.

number.toFixed( [digits] )

digits ondalık basamaktan sonra görüntülenecek basamak sayısıdır.


2
Bunun bir sayı olduğunu bilmediğiniz sürece güvensizdir .
david.pfx

6

Kullandığım https://jsperf.com aşağıdaki durumlar için bir test vakası oluşturmak için:

number + ''
`${number}`
String(number)
number.toString()

https://jsperf.com/number-string-conversion-speed-comparison

24 Temmuz 2018 itibariyle sonuçlar number + '', Chrome'da, şablon dizgisi değişmezleriyle bağlanan Firefox'ta en hızlı olduğunu gösteriyor.

Her ikisi String(number)de ve number.toString()en hızlı seçenekten yaklaşık% 95 daha yavaş.

performans testleri, yukarıdaki açıklama


2

Okuması daha kolay olduğu için ilk ikisini seviyorum. Kullanmaya meyilliyim String(n)ama bu her şeyden çok bir tarz meselesi.

Yani bir çizginiz olmadığı sürece

var n = 5;
console.log ("the number is: " + n);

ki bu çok açıklayıcı


2

Ben duruma bağlı olduğunu düşünüyorum ama yine de .toString()anlamak için çok açık olduğu gibi yöntemi kullanabilirsiniz .


2

.toString () yerleşik daktilo işlevidir, bu ayrıntılar için uzman değilim ama yerleşik tip döküm ayet açık metodolojileri karşılaştırdığımızda, yerleşik geçici çözümler her zaman tercih edilir.


1

Eğer her şeyi göz önünde bulundurmam gerekirse,

var myint = 1;
var mystring = myint + '';
/*or int to string*/
myint = myint + ''

IMHO, dizeye dönüştürmenin en hızlı yolu. Yanlışım varsa düzelt.


1

Mevcut ve gelecekteki olası tüm vakalar için tek geçerli çözüm (girdi sayı, null, undefined, Symbol, başka bir şeydir) String(x). "Burada kesinlikle sayı dizeye ve burada kesinlikle boole dize" gibi değer türü varsayımlarına dayanarak, basit bir işlem için 3 yol kullanmayın.

Açıklama:

String(x)null, undefined, Semboller, [herhangi bir şey] ve .toString()nesneleri çağırır .

'' + x.valueOf()x'e yapılan çağrılar (sayıya döküm), Sembolleri atar, uygulamaya bağlı sonuçlar sağlayabilir.

x.toString() null ve undefined atar.

Not: String(x)yine de prototipsiz nesnelerde başarısız olur Object.create(null).

'Merhaba, tanımsız' gibi dizeleri sevmiyorsanız veya prototipsiz nesneleri desteklemek istiyorsanız, aşağıdaki tür dönüştürme işlevini kullanın:

/**
 * Safely casts any value to string. Null and undefined are converted to ''.
 * @param  {*} value
 * @return {string}
 */
function string (str) {
  return value == null ? '' : (typeof value === 'object' && !value.toString ? '[object]' : String(value));
}

1

Sayı değişmezlerinde, bir özelliğe erişim noktasının ondalık noktadan ayrılması gerekir. 123 rakamsal sayısında String () işlevini çağırmak istiyorsanız, bu size aşağıdaki seçenekleri sunar:

123..toString()
123 .toString() // space before the dot 123.0.toString()
(123).toString()

1

JS'de bir tamsayı dizeye dönüştürmek için yöntemler

Yöntemler, azalan performans sırasıyla düzenlenmiştir.

(Performans testi sonuçları @DarckBlezzer tarafından yanıtında verilmiştir)

var num = 1

Yöntem 1:

num = `$ {num}`

Yöntem 2:

num = num + ''

Yöntem 3:

num = Dize (num)

Yöntem 4:

num = num.toString ()

Not: Bir numaradan doğrudan tostring () yöntemini çağıramazsınız

Örneğin: 2.toString () yakalanmamış Syntax hatası atacak Hata : Geçersiz veya beklenmeyen simge


0

Hangisinin en iyi performans sergilediğini merak ediyorsanız, tüm farklı Number -> String dönüşümlerini karşılaştırdığımda bunu kontrol edin.

En hızlı gibi 2+''veya 2+""öyle görünüyor .

https://jsperf.com/int-2-string


0

String yapıcısını da kullanabiliriz . Bu karşılaştırmaya göre " + num, popüler tarayıcı Google Chrome'dan daha yavaş olsa da, bir sayıyı Firefox 58'de String'e dönüştürmenin en hızlı yolu .


0

Yöntem toFixed()aynı zamanda amacı çözecektir.

var n = 8.434332;
n.toFixed(2)  // 8.43

0

NumberNesneyi çağırabilir ve sonra çağırabilirsiniz toString().

Number.call(null, n).toString()

Bu hileyi başka bir javascript yerel nesnesi için kullanabilirsiniz.


0

Son zamanlarda bununla karşılaşmak, yöntem 3 ve 4 uygun değildir, çünkü dizelerin nasıl kopyalanıp birleştirildiği. Küçük bir program için bu sorun önemsizdir, ancak herhangi bir gerçek web uygulaması için frekans dizisi manipülasyonları ile uğraşmamız gereken bu eylem performansı ve okunabilirliği etkileyebilir.

İşte okuma bağlantısı .


0

Zamanım olduğunda bunu daha fazla veriyle yeniden düzenleyeceğim, çünkü şu anda bu iyi ...

Düğümlerde Test v8.11.2: 2018/06/06

let i=0;
    console.time("test1")
    for(;i<10000000;i=i+1){
    	const string = "" + 1234;
    }
    console.timeEnd("test1")
    
    i=0;
    console.time("test1.1")
    for(;i<10000000;i=i+1){
    	const string = '' + 1234;
    }
    console.timeEnd("test1.1")
    
    i=0;
    console.time("test1.2")
    for(;i<10000000;i=i+1){
    	const string = `` + 1234;
    }
    console.timeEnd("test1.2")
    
    i=0;
    console.time("test1.3")
    for(;i<10000000;i=i+1){
    	const string = 1234 +  '';
    }
    console.timeEnd("test1.3")
    
    
    i=0;
    console.time("test2")
    for(;i<10000000;i=i+1){
    	const string = (1234).toString();
    }
    console.timeEnd("test2")
    
    
    i=0;
    console.time("test3")
    for(;i<10000000;i=i+1){
    	const string = String(1234);
    }
    console.timeEnd("test3")
    
    
    i=0;
    console.time("test4")
    for(;i<10000000;i=i+1){
    	const string = `${1234}`;
    }
    console.timeEnd("test4")
    
    i=0;
    console.time("test5")
    for(;i<10000000;i=i+1){
    	const string = 1234..toString();
    }
    console.timeEnd("test5")
    
    i=0;
    console.time("test6")
    for(;i<10000000;i=i+1){
    	const string = 1234 .toString();
    }
    console.timeEnd("test6")

çıktı

test1: 72.268ms
test1.1: 61.086ms
test1.2: 66.854ms
test1.3: 63.698ms
test2: 207.912ms
test3: 81.987ms
test4: 59.752ms
test5: 213.136ms
test6: 204.869ms

Yay - test4 düzenli olarak kullandığım şey !!
Adrian Bartholomew

0

Node.js kullanılırken benzer sonuçlar görünüyor. Bu senaryoyu çalıştırdım:

let bar;
let foo = ["45","foo"];

console.time('string concat testing');
for (let i = 0; i < 10000000; i++) {
    bar = "" + foo;
}
console.timeEnd('string concat testing');


console.time("string obj testing");
for (let i = 0; i < 10000000; i++) {
    bar = String(foo);
}
console.timeEnd("string obj testing");

console.time("string both");
for (let i = 0; i < 10000000; i++) {
    bar = "" + foo + "";
}
console.timeEnd("string both");

ve aşağıdaki sonuçları elde etti:

 node testing.js
string concat testing: 2802.542ms
string obj testing: 3374.530ms
string both: 2660.023ms

Her seferinde koştuğumda da benzer.

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.