ความแตกต่างระหว่าง String.slice และ String.substring คืออะไร?


833

ไม่มีใครรู้ว่าความแตกต่างระหว่างสองวิธีนี้คืออะไร?

String.prototype.slice
String.prototype.substring

215
มันเป็นตัวอย่างของการออกแบบที่ไม่ดีของจาวาสคริปต์ที่เราลงเอยด้วยสามวิธีที่ทุกคนทำสิ่งเดียวกัน แต่ด้วยนิสัยใจคอที่แตกต่างกัน IMO sliceเป็นสิ่งที่มีพฤติกรรมที่ไม่คาดคิดน้อยที่สุด
bobince

2
สตริงย่อย IMO เมื่อใช้เพื่อซับสตริงจาก idx จนถึงจุดสิ้นสุดสามารถเข้าใจได้ง่ายขึ้น โดยเฉพาะอย่างยิ่งกับ noobs
mplungjan

1
ตามที่เว็บไซต์นี้ , sliceจริงสามารถแทนที่substringและมีเหตุผลที่จะใช้มันไม่มี
Derek 朕會功夫

5
@AmolMKulkarni ไม่จริงเลย ถ้าคุณพยายามที่ก็ถือว่าเป็นvar a = "asdf".substring(-1); var a = "asdf".substring(0);ไม่มีข้อยกเว้นโยน และถ้าคุณใช้var a = "asdf".substring(2, -1);จะใช้0ในสถานที่ของ-1(เหมือนก่อน) var a = "asdf".substring(0, 2);และแลกเปลี่ยนข้อโต้แย้งจึงทำหน้าที่เหมือน ฉันลองสิ่งเหล่านี้บน IE 8 และได้ผลลัพธ์โดยไม่มีข้อยกเว้น
Ian

35
"ฉันลองสิ่งเหล่านี้บน IE 8" - ฉันชอบการเขียนโปรแกรม
ประหลาดใจ

คำตอบ:


859

slice()ทำงานเหมือนกับsubstring()พฤติกรรมที่แตกต่างกันเล็กน้อย

Syntax: string.slice(start, stop);
Syntax: string.substring(start, stop);

สิ่งที่พวกเขามีเหมือนกัน:

  1. ถ้าstartเท่ากับstop: ส่งคืนสตริงว่าง
  2. ถ้าstopไม่ได้ระบุไว้: แยกอักขระที่ส่วนท้ายของสตริง
  3. หากอาร์กิวเมนต์อย่างใดอย่างหนึ่งมากกว่าความยาวของสตริงความยาวของสตริงจะถูกนำมาใช้แทน

ความแตกต่างของ :substring()

  1. ถ้าเป็นstart > stopเช่นนั้นsubstringจะแลกเปลี่ยนข้อโต้แย้งทั้งสอง
  2. ถ้าอาร์กิวเมนต์ทั้งเป็นลบหรือเป็นก็จะได้รับการปฏิบัติราวกับว่ามันเป็นNaN0

ความแตกต่างของ :slice()

  1. ถ้าstart > stop, slice()จะกลับสตริงที่ว่างเปล่า ( "")
  2. ถ้าstartเป็นลบ: ตั้งค่าถ่านจากจุดสิ้นสุดของสตริงเหมือนกับsubstr()ใน Firefox พฤติกรรมนี้พบได้ทั้งใน Firefox และ IE
  3. ถ้าstopเป็นลบ: ชุดหยุด: string.length – Math.abs(stop)(ค่าเดิม) ยกเว้นขอบเขตที่ 0 (ดังนั้นMath.max(0, string.length + stop)) ขณะที่ครอบคลุมในข้อกำหนด ECMA

ที่มา: ศิลปะขั้นพื้นฐานของการเขียนโปรแกรมและพัฒนา: Javascript: substr () vs substring ()


8
ในบันทึกย่อล่าสุดของคุณslice()ควรเป็นstring.length - stop
Andy

16
ในบันทึกล่าสุดของคุณบนslice()ผมคิดว่ามันควรจะเป็น(string.length – 1) + stopหรือจะทำให้มันชัดเจนว่ามันเป็นเชิงลบ(string.length – 1) – Math.abs(stop)
Oriol

9
@Longpoke: ถูกเพิ่มเพื่อให้มีวิธีการที่สอดคล้องกับสตริงString.slice อยู่ที่นั่นตลอดไปดังนั้นพวกเขาจึงไม่ทำลายมันและเพิ่มวิธีอื่น การตัดสินใจที่เส็งเคร็งเป็น 1. ความสอดคล้องเป็นสิ่งที่ดีและ 2 ช่วยให้ไวยากรณ์การแบ่งส่วนของ CoffeeScript ทำงานบนอาร์เรย์และสตริง @Oriol: แก้ไขได้ค่ะArray.slicesubstring
แกะบิน

6
ดูเหมือนว่าจะมีความแตกต่างของประสิทธิภาพการทำงานระหว่างซับ
Rick

4
แอนดี้พูดถูก stopจะถูกตั้งค่าเป็นstring.length + stopถ้าstopเป็นค่าลบ โปรดจำไว้ว่าstopดัชนีคือดัชนีหลังจากแยกอักขระตัวสุดท้าย!
user1537366

97

หมายเหตุ: หากคุณกำลังรีบและ / หรือมองหาคำตอบสั้น ๆ เลื่อนไปที่ด้านล่างของคำตอบและอ่านสองบรรทัดสุดท้ายหากไม่รีบอ่านสิ่งทั้งหมด


ให้ฉันเริ่มต้นด้วยการระบุข้อเท็จจริง:

ไวยากรณ์:
string.slice(start,end)
string.substr(start,length)
string.substring(start,end)
หมายเหตุ # 1:slice()==substring()

มันทำอะไร สารสกัดจากวิธีส่วนของสตริงและผลตอบแทนส่วนขยายในสตริงใหม่ สารสกัดจากวิธีส่วนของสตริงเริ่มต้นที่ตัวละครในตำแหน่งที่กำหนดและผลตอบแทนตามจำนวนที่ระบุของตัวละคร สารสกัดจากวิธีส่วนของสตริงและผลตอบแทนส่วนขยายในสตริงใหม่ โน้ต 2:
slice()
substr()
substring()
slice()==substring()

เปลี่ยนสตริงดั้งเดิมหรือไม่
slice()ไม่
substr()ไม่
substring()ไม่
หมายเหตุ # 3:slice()==substring()

การใช้ตัวเลขติดลบเป็นอาร์กิวเมนต์:
slice()เลือกอักขระที่เริ่มต้นจากจุดสิ้นสุดของสตริง
substr()เลือกอักขระที่เริ่มต้นจากจุดสิ้นสุดของสตริง
substring()ไม่ดำเนินการ
หมายเหตุ # 3:slice()==substr()

ถ้าอาร์กิวเมนต์แรกมีค่ามากกว่าสอง:
slice()ไม่ทำงาน
substr()เนื่องจากอาร์กิวเมนต์ที่สองไม่ใช่ตำแหน่ง แต่มีค่าความยาวมันจะทำงานตามปกติโดยไม่มีปัญหา
substring()จะสลับอาร์กิวเมนต์ทั้งสองและดำเนินการตามปกติ

อาร์กิวเมนต์แรก:
slice()จำเป็น, หมายถึง: ดัชนีเริ่มต้นที่
substr()จำเป็น, หมายถึง: ดัชนีเริ่มต้นที่
substring()ต้องการ, บ่งชี้: ดัชนีเริ่มต้น
หมายเหตุ 4:slice()==substr()==substring()

อาร์กิวเมนต์ที่สอง:
slice()ตัวเลือกตำแหน่ง (ไม่เกิน แต่ไม่รวม) ตำแหน่งที่จะสิ้นสุดการแยก
substr()ตัวเลือกจำนวนอักขระที่จะแตก
substring()ตัวเลือกตำแหน่ง (ขึ้นไป แต่ไม่รวม) ซึ่งจะสิ้นสุดที่การแยก
หมายเหตุ # 5:slice()==substring()

เกิดอะไรขึ้นถ้าอาร์กิวเมนต์ที่สองถูกละเว้น
slice()เลือกอักขระทั้งหมดจากตำแหน่งเริ่มต้นไปยังจุดสิ้นสุดของสตริง
substr()เลือกอักขระทั้งหมดจากตำแหน่งเริ่มต้นไปยังจุดสิ้นสุดของสตริง
substring()เลือกอักขระทั้งหมดจากตำแหน่งเริ่มต้นถึงจุดสิ้นสุดของสตริง
หมายเหตุ # 6:slice()==substr()==substring()

เพื่อให้คุณสามารถพูดได้ว่ามีความแตกต่างระหว่างslice()และsubstr()ในขณะนั้นเป็นสำเนาของsubstring()slice()

ในการสรุป:
ถ้าคุณรู้ว่าดัชนี (ตำแหน่ง) ที่คุณจะหยุด ( แต่ไม่รวม) ใช้ถ้าคุณรู้ว่าความยาวของตัวละครที่จะสกัดการใช้งานslice()
substr()


11

24

Ben Nadel ได้เขียนบทความที่ดีเกี่ยวกับเรื่องนี้เขาชี้ให้เห็นความแตกต่างในพารามิเตอร์ของฟังก์ชั่นเหล่านี้:

String.slice( begin [, end ] )
String.substring( from [, to ] )
String.substr( start [, length ] )

นอกจากนี้เขายังชี้ให้เห็นว่าหากพารามิเตอร์ของการแบ่งเป็นลบจะอ้างอิงสตริงจากจุดสิ้นสุด สตริงย่อยและสตริงย่อยไม่

นี่คือบทความของเขาเกี่ยวกับเรื่องนี้


3
สิ่งนี้ไม่ถูกต้อง substr จัดการกับพารามิเตอร์เชิงลบ '0123456789'.substr(-3, 2) -> '78'
Neil Fraser

14

คำตอบเดียวดี แต่ต้องอ่านเล็กน้อย โดยเฉพาะอย่างยิ่งกับคำศัพท์ใหม่ "หยุด"

My Go - จัดโดยความแตกต่างเพื่อให้มีประโยชน์นอกเหนือจากคำตอบแรกโดย Daniel ด้านบน:

1) ดัชนีเชิงลบ ซับสตริงต้องการดัชนีบวกและจะตั้งค่าดัชนีลบเป็น 0 ดัชนีลบของชิ้นหมายถึงตำแหน่งจากจุดสิ้นสุดของสตริง

"1234".substring(-2, -1) == "1234".substring(0,0) == ""
"1234".slice(-2, -1) == "1234".slice(2, 3) == "3"

2) การสลับดัชนี ซับสตริงจะเรียงลำดับดัชนีใหม่เพื่อให้ดัชนีแรกน้อยกว่าหรือเท่ากับดัชนีที่สอง

"1234".substring(3,2) == "1234".substring(2,3) == "3"
"1234".slice(3,2) == ""

--------------------------

ความคิดเห็นทั่วไป - ฉันคิดว่ามันแปลกที่ดัชนีที่สองคือตำแหน่งหลังจากอักขระตัวสุดท้ายของชิ้นหรือซับสตริง ฉันคาดว่า "1234" .slice (2,2) จะกลับมา "3" สิ่งนี้ทำให้ความสับสนของแอนดี้เหนือเหตุผลที่เป็นธรรม - ฉันคาดว่า "1234" .slice (2, -1) จะกลับมา "34" ใช่นี่หมายความว่าฉันใหม่กับ Javascript นี่หมายถึงพฤติกรรมเช่นนี้ด้วย:

"1234".slice(-2, -2) == "", "1234".slice(-2, -1) == "3", "1234".slice(-2, -0) == "" <-- you have to use length or omit the argument to get the 4.
"1234".slice(3, -2) == "", "1234".slice(3, -1) == "", "1234".slice(3, -0) == "" <-- same issue, but seems weirder.

2c ของฉัน


11

ความแตกต่างระหว่างสตริงย่อยและชิ้น - เป็นวิธีที่พวกเขาทำงานกับเชิงลบและสามารถมองเห็นข้อโต้แย้งของเส้นต่างประเทศ:

ซับสตริง (เริ่มต้น, สิ้นสุด)

ข้อโต้แย้งเชิงลบถูกตีความว่าเป็นศูนย์ ค่าที่มีขนาดใหญ่เกินไปจะถูกตัดให้สั้นลงตามความยาวของสตริง: alert ("testme" .substring (-2)); // "testme", -2 กลายเป็น 0

นอกจากนี้หาก start> end อาร์กิวเมนต์จะถูกสับเปลี่ยนนั่นคือบรรทัดการพล็อตจะส่งกลับระหว่างจุดเริ่มต้นและจุดสิ้นสุด:

alert ( "testme" .substring (4, -1)); // "test"
// -1 Becomes 0 -> got substring (4, 0)
// 4> 0, so that the arguments are swapped -> substring (0, 4) = "test"

ชิ้น

ค่าลบถูกวัดจากจุดสิ้นสุดของบรรทัด:

alert ( "testme" .slice (-2)); // "me", from the end position 2
alert ( "testme" .slice (1, -1)); // "estm", from the first position to the one at the end.

สะดวกกว่าสตริงย่อยลอจิกแปลก ๆ

ค่าลบของพารามิเตอร์แรกไปยัง substr รองรับในเบราว์เซอร์ทั้งหมดยกเว้น IE8-

หากการเลือกหนึ่งในสามวิธีนี้สำหรับใช้ในสถานการณ์ส่วนใหญ่ - มันจะเป็นส่วนแบ่ง : ข้อโต้แย้งเชิงลบและจะรักษาและดำเนินการอย่างชัดเจนที่สุด


4

substr: มันทำให้เราสามารถดึงส่วนหนึ่งของสตริงตามดัชนีที่ระบุ ไวยากรณ์ของ substr- string.substr (เริ่มต้นสิ้นสุด) เริ่มต้น - ดัชนีเริ่มต้นบอกที่เริ่มดึง end - end index จะบอกถึงตำแหน่งที่ดึงสตริง มันเป็นตัวเลือก

ชิ้น: มันมีไว้เพื่อดึงส่วนหนึ่งของสตริงตามดัชนีที่ระบุ มันช่วยให้เราสามารถระบุค่าบวกและดัชนี ไวยากรณ์ของ slice - string.slice (start, end) start - start index บอกตำแหน่งที่เริ่มดึงข้อมูลดัชนีสิ้นสุด - สิ้นสุดของมันบอกถึงตำแหน่งที่ดึงสตริง มันเป็นตัวเลือก ใน 'รอยต่อ' ทั้งดัชนีเริ่มต้นและจุดสิ้นสุดจะช่วยให้ดัชนีเป็นบวกและลบ

โค้ดตัวอย่างสำหรับ 'ชิ้น' ในสตริง

var str="Javascript";
console.log(str.slice(-5,-1));

output: crip

โค้ดตัวอย่างสำหรับ 'substring' ในสตริง

var str="Javascript";
console.log(str.substring(1,5));

output: avas

[* หมายเหตุ: การจัดทำดัชนีเชิงลบเริ่มต้นที่ส่วนท้ายของสตริง]


3

ความแตกต่างเพียงอย่างเดียวระหว่างวิธีการแบ่งและวิธีการย่อยเป็นของอาร์กิวเมนต์

ทั้งสองรับข้อโต้แย้งเช่นเริ่มต้น / จากและสิ้นสุด / ถึง

คุณไม่สามารถส่งค่าลบเป็นอาร์กิวเมนต์แรกสำหรับวิธีการสตริงย่อยแต่สำหรับวิธีการแบ่งการสำรวจจากปลาย

รายละเอียดอาร์กิวเมนต์เมธอด Slice:

REF: http://www.thesstech.com/javascript/string_slice_method

ข้อโต้แย้ง

start_index ดัชนีจากตำแหน่งที่ควรเริ่มต้น หากมีการระบุค่าเป็นลบแสดงว่าเริ่มจากครั้งสุดท้าย เช่น -1 สำหรับอักขระตัวสุดท้าย end_index ดัชนีหลังจากสิ้นสุดชิ้น หากไม่มีการแบ่งส่วนจะถูกนำมาจาก start_index ไปยังจุดสิ้นสุดของสตริง ในกรณีที่ดัชนีค่าลบจะถูกวัดจากจุดสิ้นสุดของสตริง

รายละเอียดอาร์กิวเมนต์ของเมธอดย่อย:

REF: http://www.thesstech.com/javascript/string_substring_method

ข้อโต้แย้ง

จาก มันควรจะเป็นจำนวนเต็มลบเพื่อระบุดัชนีจากที่สตริงย่อยควรเริ่มต้น เพื่อ จำนวนเต็มเชิงลบที่ไม่ใช่ตัวเลือกที่จะให้ดัชนีก่อนซึ่งสตริงย่อยควรจะแล้วเสร็จ


0

สำหรับslice(start, stop)หากstopเป็นลบstopจะถูกตั้งค่าเป็น:

string.length  Math.abs(stop)

ค่อนข้างมากกว่า:

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