วิธีที่ดีที่สุดในการแปลงตัวเลขเป็นสตริงใน JavaScript คืออะไร


517

อะไรคือ "วิธีที่ดีที่สุด" ในการแปลงตัวเลขเป็นสตริง (ในแง่ของความได้เปรียบด้านความเร็วความได้เปรียบที่ชัดเจนความได้เปรียบของหน่วยความจำ ฯลฯ )

ตัวอย่างบางส่วน:

  1. String(n)

  2. n.toString()

  3. ""+n

  4. n+""

คำตอบ:


516

แบบนี้:

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

ที่จริงแล้วถึงแม้ว่าฉันมักจะทำแบบนี้เพื่อความสะดวกง่าย ๆ แต่การวนซ้ำกว่า 1,000 ครั้งที่ปรากฏขึ้นเพื่อความรวดเร็วมีข้อดีสำหรับ.toString()

ดูการทดสอบประสิทธิภาพที่นี่ (ไม่ใช่โดยฉัน แต่พบได้เมื่อฉันเขียนเอง): http://jsben.ch/#/ghQYR

เร็วที่สุดจากการทดสอบ JSPerf ด้านบน: str = num.toString();

มันควรจะตั้งข้อสังเกตว่าแตกต่างในความเร็วที่ไม่ได้เป็นอย่างมีนัยสำคัญมากเกินไปเมื่อคุณพิจารณาว่าจะสามารถทำแปลงทางใดทางหนึ่ง1 ล้านครั้งใน 0.1 วินาที

อัปเดต:ความเร็วดูเหมือนจะแตกต่างกันอย่างมากจากเบราว์เซอร์ ใน Chrome num + ''ดูเหมือนว่าจะเร็วที่สุดตามการทดสอบนี้http://jsben.ch/#/ghQYR

อัปเดต 2:อีกครั้งจากการทดสอบของฉันข้างต้นควรสังเกตว่า Firefox 20.0.1 ทำงาน.toString()ช้ากว่า'' + numตัวอย่างประมาณ 100 เท่า


58
มีหลายกรณีที่แปลงอาจไม่กลับมาเป็นคำตอบที่ดีกว่าคือผลตอบแทน'' + 123e-50 "1.23e-48"
hongymagic

21
@hongymagic: คำตอบนั้นในความเป็นจริงสิ่งเดียวที่เป็นไปได้: จำนวนไม่สนใจหรือไม่รู้ว่ามันถูกป้อนเข้ามาอย่างไรและการพิมพ์มาตรฐานแทนด้วยตัวเลขหนึ่งหลักตรงจุด
Svante

4
ฉันทำการทดสอบในjsben.ch/ghQYRทุกครั้งที่มันแสดงให้ฉันเห็นผลลัพธ์ที่แตกต่าง!
Maryam Saeidi

2
ฉันชอบคำตอบนี้เพราะnull fooไม่มีข้อผิดพลาด
ttugates

2
@MaryamSaeidi: การใช้drublic 's jsperf.comทดสอบข้างต้นดูเหมือนว่าสอดคล้องกันมากขึ้น
Giraldi

364

ในความคิดของฉันn.toString()รับรางวัลเพื่อความชัดเจนและฉันไม่คิดว่ามันจะมีค่าใช้จ่ายเพิ่มเติมใด ๆ


มันมีค่าใช้จ่ายบางอย่างแม้ว่าจะไม่สำคัญในเบราว์เซอร์เวอร์ชันล่าสุด ใน Firefox Quantum อย่างน้อย
peterchaula

11
สิ่งนี้ไม่ปลอดภัย n อาจเป็นโมฆะหรือไม่ได้กำหนด
david.pfx

20
@ david.pfx คำถามถามถึงวิธีการแปลงค่าตัวเลขให้เป็นสตริง ให้ตัวอย่างของค่าที่ไม่ใช่ตัวเลข (เช่นnull, undefined) ที่จะไม่ได้ทำงานกับคำตอบนี้แทบจะไม่ทำให้มัน "ไม่ปลอดภัย"
Michael Martin-Smucker

5
@ MichaelMartin-Smucker: ถ้าคุณเขียน JS จำนวนมากคุณจะรู้ว่าสิ่งต่าง ๆ ไม่ค่อยจะแห้งและแห้ง คำถามนั้นเปิดอยู่และอย่างน้อยคำตอบที่ดีของ IMO ก็ควรที่จะรับทราบปัญหาของสตริงที่เป็นจริงหรือไม่ได้กำหนด YMMV
david.pfx

@ david.pfx ฉันเขียน js เป็นจำนวนมากและฉันจำไม่ได้ว่าครั้งสุดท้ายที่ฉันต้องการตัวเลขเป็นสตริงและอะไรก็ตาม แต่ตัวเลขที่เป็นสตริงจะพอเพียง นี่คือคำตอบที่ถูกต้อง ไม่มีคำตอบสำหรับการจัดการnullหรือundefinedเป็นแอพพลิเคชั่นที่เฉพาะเจาะจงในขณะที่ฉันจินตนาการ(n || defaultNumber).toString() ว่าสิ่งที่คนส่วนใหญ่ต้องการในสถานการณ์เช่นนี้ฉันไม่เห็นด้วยอย่างยิ่งที่เราควรทำงานกับคำถามทั้งหมด สิ่งนี้เกี่ยวกับการแปลงตัวเลขเป็นสตริงสถาปัตยกรรมที่ดีและการแปลงประเภทอื่น ๆ ที่จำเป็นต้องใช้เป็นบทเรียนแยกต่างหาก
George Reith

73

การแปลงอย่างชัดเจนมีความชัดเจนสำหรับคนที่ไม่คุ้นเคยกับภาษา การใช้ประเภทการข่มขู่ตามที่คนอื่นแนะนำจะนำไปสู่ความกำกวมหากนักพัฒนาไม่ได้ตระหนักถึงกฎการบีบบังคับ ท้ายที่สุดเวลาของนักพัฒนาซอฟต์แวร์นั้นมีค่าใช้จ่ายสูงกว่าเวลา CPU ดังนั้นฉันจะปรับให้เหมาะที่สุดสำหรับค่าใช้จ่ายในอดีต ที่ถูกกล่าวว่าในกรณีนี้ความแตกต่างนั้นมีความสำคัญน้อยมาก แต่ถ้าไม่ใช่ฉันมั่นใจว่ามีตัวบีบอัด JavaScript ที่เหมาะสมที่จะปรับสิ่งเหล่านี้ให้เหมาะสม

ดังนั้นด้วยเหตุผลดังกล่าวข้างต้นผมไปกับ: หรือ n.toString() อาจเป็นทางเลือกที่ดีกว่าเพราะจะไม่ล้มเหลวหากเป็นโมฆะหรือไม่ได้กำหนดString(n)String(n)n


12
คำถามที่ได้รับเกี่ยวกับการแปลงตัวเลขไม่ได้เกี่ยวกับการแปลงตัวเลขหรือหรือnull undefinedหากnเป็นnullหรือundefinedเนื่องจากข้อผิดพลาดในโปรแกรมของฉันแล้วฉันต้องการโปรแกรมของฉันที่จะล้มเหลวในรัฐนี้จะให้ฉันมีโอกาสที่ดีในการหาและแก้ไขข้อผิดพลาด การขัดข้องของโปรแกรมเป็นของขวัญให้โปรแกรมเมอร์เพื่อช่วยเธอค้นหาข้อบกพร่อง :-) อีกทางเลือกหนึ่งคือส่งมอบซอฟต์แวร์ที่ไม่ทำงานตามที่ได้ออกแบบไว้ ดังนั้นฉันไม่ใช่แฟนของการใช้String(n)เพื่อปกปิดข้อผิดพลาด
แมตต์วอลลิซ

1
String(n)_.compose(funcThatNeedsAStringParam, String)เป็นสิ่งที่ดีสำหรับการใช้ในรูปแบบการทำงานเช่นกับขีดรวม
Rik Martins

2
String (null) จะไม่ผิดพลาด progam แต่จะส่งคืนสตริงตัวอักษร "null" ซึ่งอาจไม่ใช่สิ่งที่คุณต้องการ หากข้อมูลนั้นอาจเป็นโมฆะอย่างถูกต้องคุณจะต้องจัดการอย่างชัดเจน
Peter Smartt

1
@ Mattall ฉันคิดว่ามันควรจะเป็นการตัดสินใจของนักพัฒนาไม่ใช่ผู้ตอบใช่ไหมคุณคิดยังไง?
forresthopkinsa

30

... โปรแกรมแยกวิเคราะห์ของจาวาสคริปต์พยายามที่จะแยกวิเคราะห์สัญกรณ์จุดในตัวเลขเป็นตัวอักษรจุดลอยตัว

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

แหล่ง


17

เห็นได้ชัดว่าลิ้นในแก้ม:

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

หรือใน ES6 คุณสามารถใช้เทมเพลตสตริง :

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

ถ้าฉันใช้การวัดประสิทธิภาพด้วยเทมเพลต ES6 บางครั้งมันก็พิสูจน์ได้ว่าเร็วกว่า'' + numberวิธีนี้ สิ่งนี้กล่าวว่าผลลัพธ์ของการวัดประสิทธิภาพเหล่านี้มีความแตกต่างกันอย่างมากเมื่อทำการแสดงหลาย ๆ ครั้งดังนั้นไม่แน่ใจว่าควรจะจริงจังเกินไปหรือไม่
Nico Van Belle

15

คำตอบอื่น ๆ ครอบคลุมตัวเลือกอื่น ๆ อยู่แล้ว แต่ฉันชอบสิ่งนี้:

s = `${n}`

สั้นกระชับใช้อยู่แล้วในหลาย ๆ ที่ (ถ้าคุณใช้เฟรมเวิร์กสมัยใหม่ / เวอร์ชั่น ES) ดังนั้นจึงเป็นเรื่องที่ปลอดภัยที่นักเขียนโปรแกรมจะเข้าใจ

ไม่ว่ามัน (ปกติ) ที่สำคัญมาก แต่ก็ยังน่าจะเป็นในหมู่ที่เร็วที่สุดเมื่อเทียบกับวิธีการอื่น


นอกจากนี้ยังปลอดภัยหาก n อาจไม่ใช่ตัวเลข
david.pfx

แต่อย่างn.toString()นั้นใช่มั้ย
พฤศจิกายน

1
@ หากnมีundefinedปัญหาจะทำให้เกิดข้อผิดพลาดทางไวยากรณ์โดยใช้.toString()
Jee Mok

สิ่งนี้ไม่เพียงให้ผลเช่นเดียวกับString(n)ในทุกกรณีใช่หรือไม่ ข้อแตกต่างคือมันชัดเจนน้อยกว่า
Bennett McElwee

และช้ากว่ามาก
Adrian Bartholomew

12

วิธีที่ง่ายที่สุดในการแปลงตัวแปรให้เป็นสตริงคือการเพิ่มสตริงว่างให้กับตัวแปรนั้น

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

2
โปรดทราบว่ามันจะต้องอยู่ใน parens: (5.41 + '')เพื่อใช้วิธีการ String เช่น.substring()และคนอื่น ๆ
Gjaa

ทำไมถึงต้องมีการจดบันทึก?
Adrian Bartholomew

7

หากคุณต้องการจัดรูปแบบผลลัพธ์เป็นจำนวนทศนิยมเฉพาะเช่นเพื่อเป็นตัวแทนของสกุลเงินคุณต้องมีtoFixed()วิธีเช่นนั้น

number.toFixed( [digits] )

digits คือจำนวนหลักที่จะแสดงหลังจุดทศนิยม


2
ไม่ปลอดภัยเว้นแต่คุณจะรู้ว่าเป็นตัวเลข
david.pfx

6

ฉันใช้https://jsperf.comเพื่อสร้างกรณีทดสอบสำหรับกรณีต่อไปนี้:

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

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

ตั้งแต่วันที่ 24 กรกฎาคม 2018 ผลลัพธ์บอกว่าnumber + ''เร็วที่สุดใน Chrome ใน Firefox ที่สัมพันธ์กับตัวอักษรสตริงเทมเพลต

ทั้งสองString(number)และnumber.toString()ช้ากว่าตัวเลือกที่เร็วที่สุดประมาณ 95%

การทดสอบประสิทธิภาพคำอธิบายข้างต้น


2

ฉันชอบสองคนแรกเนื่องจากอ่านง่ายกว่า ฉันมักจะใช้String(n)แต่มันเป็นเรื่องของสไตล์มากกว่าสิ่งอื่นใด

นั่นคือถ้าคุณมีสายเป็น

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

ซึ่งอธิบายตนเองได้มาก


2

ฉันคิดว่ามันขึ้นอยู่กับสถานการณ์ แต่อย่างไรก็ตามคุณสามารถใช้.toString()วิธีนี้ได้เพราะมันชัดเจนมากที่จะเข้าใจ


2

.toString () เป็นฟังก์ชั่น typecasting ในตัวฉันไม่มีความเชี่ยวชาญในรายละเอียดนั้น แต่เมื่อใดก็ตามที่เราเปรียบเทียบวิธีการในการส่งคำสั่งแบบหล่อในตัว


1

หากฉันต้องพิจารณาทุกอย่างฉันจะแนะนำสิ่งต่อไปนี้

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

IMHO เป็นวิธีที่เร็วที่สุดในการแปลงเป็นสตริง ถูกต้องฉันถ้าฉันผิด


1

เพียงวิธีการแก้ปัญหาที่ถูกต้องสำหรับเกือบทั้งหมดที่เป็นไปได้กรณีที่มีอยู่และในอนาคต (input เป็นจำนวนโมฆะไม่ได้กำหนดสัญลักษณ์สิ่งอื่น) String(x)เป็น อย่าใช้ 3 วิธีในการดำเนินการอย่างง่ายโดยอิงตามสมมติฐานประเภทค่าเช่น "ที่นี่ฉันแปลงตัวเลขเป็นสตริงและที่นี่เป็นบูลีนเป็นสตริง"

คำอธิบาย:

String(x)จัดการค่า null, ไม่ได้กำหนด, สัญลักษณ์, [อะไร] และการเรียก.toString()ใช้วัตถุ

'' + xการเรียก.valueOf()ใช้ x (การชี้ไปยังหมายเลข), ใช้สัญลักษณ์เพื่อให้ผลลัพธ์ที่ขึ้นอยู่กับการใช้งาน

x.toString() โยนเป็นโมฆะและไม่ได้กำหนด

หมายเหตุ: จะยังคงล้มเหลวในวัตถุต้นแบบน้อยเช่นString(x)Object.create(null)

หากคุณไม่ชอบสตริงเช่น 'Hello, undefined' หรือต้องการสนับสนุนวัตถุต้นแบบที่น้อยกว่าให้ใช้ฟังก์ชั่นการแปลงประเภทต่อไปนี้:

/**
 * 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

ด้วยตัวอักษรตัวเลขจุดสำหรับการเข้าถึงคุณสมบัติจะต้องแตกต่างจากจุดทศนิยม สิ่งนี้จะทำให้คุณมีตัวเลือกต่อไปนี้หากคุณต้องการเรียกใช้ String () ที่ตัวอักษร 123:

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

1

ด้านล่างเป็นวิธีการแปลงจำนวนเต็มเป็นสตริงใน JS

วิธีการจัดเรียงตามลำดับที่ลดลงของประสิทธิภาพ

(ผลการทดสอบประสิทธิภาพมอบให้โดย @DarckBlezzer ในคำตอบของเขา)

var num = 1

วิธีที่ 1:

num = `$ {num}`

วิธีที่ 2:

num = num + ''

วิธีที่ 3:

NUM = สตริง (NUM)

วิธีที่ 4:

num = num.toString ()

หมายเหตุ: คุณไม่สามารถโทร tostring () โดยตรงจากหมายเลข

เช่น: 2.toString () จะโยน Uncaught SyntaxError : โทเค็นไม่ถูกต้องหรือไม่คาดคิด



0

นอกจากนี้เรายังสามารถใช้ตัวสร้างสตริง ตามมาตรฐานนี้มันเป็นวิธีที่เร็วที่สุดในการแปลง Number เป็น String ใน Firefox 58 แม้ว่ามันจะช้ากว่า " + numเบราว์เซอร์ยอดนิยมของ Google Chrome



0

คุณสามารถโทรหาวัตถุและการโทรแล้วNumbertoString()

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

คุณสามารถใช้เคล็ดลับนี้กับวัตถุพื้นเมืองจาวาสคริปต์อื่นได้


0

เพิ่งเจอสิ่งนี้เมื่อเร็ว ๆ นี้วิธีที่ 3 และ 4 ไม่เหมาะสมเพราะวิธีการคัดลอกสตริงแล้วรวมเข้าด้วยกัน สำหรับโปรแกรมขนาดเล็กปัญหานี้ไม่มีนัยสำคัญ แต่สำหรับเว็บแอปพลิเคชันจริง ๆ การกระทำนี้ที่เราต้องจัดการกับการจัดการสตริงความถี่อาจส่งผลกระทบต่อประสิทธิภาพและความสามารถในการอ่าน

นี่คือการเชื่อมโยงการอ่าน


0

ฉันจะแก้ไขอีกครั้งด้วยข้อมูลเพิ่มเติมเมื่อฉันมีเวลาสำหรับตอนนี้นี่เป็นเรื่องปกติ ...

ทดสอบใน nodejs 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")

เอาท์พุต

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 เป็นสิ่งที่ฉันใช้เป็นประจำ !!
เอเดรียนบาร์โธโลมิว

0

ดูเหมือนว่าผลลัพธ์ที่คล้ายกันเมื่อใช้ node.js ฉันรันสคริปต์นี้:

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");

และได้ผลลัพธ์ดังต่อไปนี้:

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

ครั้งที่คล้ายกันทุกครั้งที่ฉันวิ่ง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.