อะไรคือความแตกต่างระหว่าง string primitives และ String objects ใน JavaScript?


116

นำมาจากMDN

สตริงลิเทอรัล (แสดงโดยอัญประกาศคู่หรือเดี่ยว) และสตริงที่ส่งคืนจากการเรียกสตริงในบริบทที่ไม่ใช่ตัวสร้าง (กล่าวคือโดยไม่ใช้คีย์เวิร์ดใหม่) เป็นสตริงดั้งเดิม JavaScript จะแปลงวัตถุดั้งเดิมเป็นสตริงโดยอัตโนมัติเพื่อให้สามารถใช้วิธีการอ็อบเจ็กต์ String สำหรับสตริงดั้งเดิมได้ ในบริบทที่ต้องเรียกใช้เมธอดบนสตริงดั้งเดิมหรือการค้นหาคุณสมบัติเกิดขึ้น JavaScript จะตัดสตริงดั้งเดิมโดยอัตโนมัติและเรียกใช้เมธอดหรือดำเนินการค้นหาคุณสมบัติ

ดังนั้นฉันคิดว่าการดำเนินการ (เชิงตรรกะ) (การเรียกใช้เมธอด) บนสตริงดั้งเดิมควรจะช้ากว่าการดำเนินการกับสตริงอ็อบเจกต์เนื่องจากสตริงดั้งเดิมใด ๆ ถูกแปลงเป็นสตริงอ็อบเจ็กต์ (งานพิเศษ) ก่อนที่methodจะนำไปใช้กับสตริง

แต่ในกรณีทดสอบนี้ผลลัพธ์กลับตรงกันข้าม ป้องกันรหัส-1วิ่งเร็วกว่าบล็อก-2 รหัสทั้งบล็อกรหัสจะได้รับดังนี้

รหัสบล็อก -1:

var s = '0123456789';
for (var i = 0; i < s.length; i++) {
  s.charAt(i);
}

รหัสบล็อก -2:

var s = new String('0123456789');
for (var i = 0; i < s.length; i++) {
    s.charAt(i);
}

ผลลัพธ์จะแตกต่างกันไปในเบราว์เซอร์ แต่code block-1จะเร็วกว่าเสมอ ใครช่วยอธิบายเรื่องนี้หน่อยได้ไหมว่าทำไมcode block-1 ถึงเร็วกว่าcode block-2


6
การใช้new Stringแนะนำเลเยอร์โปร่งใสอื่นของการตัดวัตถุ typeof new String(); //"object"
Paul S.

แล้ว'0123456789'.charAt(i)ไง?
Yuriy Galanter

@YuriyGalanter มันไม่ใช่ปัญหา แต่ฉันถามว่าทำไมcode block-1เร็วกว่า?
The Alpha

2
วัตถุสตริงเป็นสิ่งที่พบเห็นได้ยากในบริบทชีวิตจริงดังนั้นจึงไม่น่าแปลกใจที่ล่ามจะเพิ่มประสิทธิภาพตัวอักษรสตริง ปัจจุบันโค้ดของคุณไม่ได้ถูกตีความเพียงอย่างเดียวมีเลเยอร์การเพิ่มประสิทธิภาพมากมายที่เกิดขึ้นเบื้องหลัง
FabrícioMatté

2
นี่เป็นเรื่องแปลก: ฉบับแก้ไข 2
hjpotter92

คำตอบ:


149

JavaScript มีสองประเภทหลักไพรไวต์และออบเจ็กต์

var s = 'test';
var ss = new String('test');

รูปแบบใบเสนอราคาเดี่ยว / คู่จะเหมือนกันในแง่ของฟังก์ชันการทำงาน นอกจากนี้พฤติกรรมที่คุณพยายามตั้งชื่อเรียกว่าการชกมวยอัตโนมัติ ดังนั้นสิ่งที่เกิดขึ้นจริงคือไพรเมอร์ถูกแปลงเป็นประเภท wrapper เมื่อมีการเรียกใช้เมธอดของประเภท Wrapper พูดง่ายๆ:

var s = 'test';

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

จะเกิดอะไรขึ้นเมื่อคุณทำs.charAt(i)เช่นนี้?

เนื่องจากsไม่ได้เป็นตัวอย่างของString, JavaScript ประสงค์อัตโนมัติกล่องsซึ่งมีtypeof stringประเภทเสื้อคลุมของตนStringด้วยหรืออย่างแม่นยำมากขึ้นtypeof objects.valueOf(s).prototype.toString.call = [object String]

พฤติกรรมการชกมวยอัตโนมัติจะเหวี่ยงsไปมาเป็นประเภท Wrapper ตามต้องการ แต่การดำเนินการมาตรฐานนั้นรวดเร็วอย่างไม่น่าเชื่อเนื่องจากคุณจัดการกับประเภทข้อมูลที่ง่ายกว่า อย่างไรก็ตามการชกมวยอัตโนมัติและObject.prototype.valueOfมีผลกระทบที่แตกต่างกัน

หากคุณต้องการบังคับให้ชกมวยอัตโนมัติหรือใช้แบบดั้งเดิมเป็นประเภท Wrapper คุณสามารถใช้ได้Object.prototype.valueOfแต่ลักษณะการทำงานจะแตกต่างกัน จากสถานการณ์การทดสอบที่หลากหลายโดยอัตโนมัติการชกมวยจะใช้เฉพาะเมธอด 'จำเป็น' เท่านั้นโดยไม่เปลี่ยนแปลงลักษณะดั้งเดิมของตัวแปร นั่นคือเหตุผลที่คุณได้รับความเร็วที่ดีขึ้น


33

สิ่งนี้ค่อนข้างขึ้นอยู่กับการนำไปใช้งาน แต่ฉันจะถ่ายทำ ฉันจะยกตัวอย่างด้วย V8 แต่ฉันถือว่าเครื่องยนต์อื่นใช้วิธีการที่คล้ายกัน

สตริงดั้งเดิมถูกแยกวิเคราะห์ไปยังv8::Stringออบเจ็กต์ ดังนั้นวิธีการที่สามารถเรียกได้โดยตรงบนมันดังกล่าวโดยjfriend00

วัตถุ String ในมืออื่น ๆ ที่จะแยกกันไปv8::StringObjectซึ่งทอดตัวและนอกเหนือจากการเป็นวัตถุที่เต็มเปี่ยมทำหน้าที่เป็นเสื้อคลุมสำหรับObjectv8::String

ตอนนี้มันเป็นเพียงตรรกะโทรไป new String('').method()มีการ unbox นี้v8::StringObject's v8::Stringก่อนที่จะดำเนินวิธีการด้วยเหตุนี้มันจะช้า


ในภาษาอื่น ๆ ค่าดั้งเดิมไม่มีวิธีการ

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

อย่างไรก็ตามเอ็นจิ้นอัจฉริยะจะไม่แปลง string primitive-yเป็น String object ทุกครั้งที่คุณต้องการเรียกใช้เมธอด นอกจากนี้ยังมีการกล่าวถึงอย่างเป็นข้อมูลในข้อมูลจำเพาะ Annotated ES5 เกี่ยวกับการแก้ไขคุณสมบัติ (และ "วิธีการ" ¹) ของค่าดั้งเดิม:

บันทึกวัตถุที่อาจถูกสร้างขึ้นในขั้นตอนที่ 1 ไม่สามารถเข้าถึงได้จากวิธีการข้างต้น การนำไปใช้งานอาจเลือกที่จะหลีกเลี่ยงการสร้างวัตถุจริง [ ... ]

ในระดับที่ต่ำมาก Strings มักจะถูกนำไปใช้เป็นค่าสเกลาร์ที่ไม่เปลี่ยนรูป ตัวอย่างโครงสร้างกระดาษห่อ:

StringObject > String (> ...) > char[]

ยิ่งคุณห่างไกลจากสิ่งดั้งเดิมมากเท่าไหร่ก็ยิ่งต้องใช้เวลานานกว่าจะไปถึงมันได้ ในทางปฏิบัติStringprimitives มีบ่อยกว่าStringObjects มากดังนั้นจึงไม่น่าแปลกใจที่เอ็นจิ้นจะเพิ่มเมธอดให้กับคลาสของอ็อบเจกต์ที่สอดคล้องกัน (ตีความ) ของ String primitives แทนที่จะแปลงกลับไปกลับมาระหว่างStringและStringObjectตามคำอธิบายของ MDN แนะนำ


¹ใน JavaScript "method" เป็นเพียงรูปแบบการตั้งชื่อสำหรับคุณสมบัติที่เปลี่ยนเป็นค่าฟังก์ชัน type


1
ยินดีต้อนรับ =]ตอนนี้ฉันสงสัยว่าคำอธิบายของ MDN มีเพียงเพราะดูเหมือนว่าจะเป็นวิธีที่ง่ายที่สุดในการทำความเข้าใจเกี่ยวกับการชกมวยอัตโนมัติหรือว่ามีการอ้างอิงในข้อกำหนด ES หรือไม่ .. การอ่านข้อมูลจำเพาะในขณะนี้เพื่อตรวจสอบจะจำไว้ว่า อัปเดตคำตอบหากฉันพบข้อมูลอ้างอิง
FabrícioMatté

ข้อมูลเชิงลึกที่ยอดเยี่ยมเกี่ยวกับการใช้งาน V8 ฉันจะเพิ่มว่ามวยไม่ได้มีไว้เพื่อแก้ไขฟังก์ชันเท่านั้น นอกจากนี้ยังมีการส่งผ่านการอ้างอิงนี้ไปยังวิธีการ ตอนนี้ฉันไม่แน่ใจว่า V8 จะข้ามสิ่งนี้สำหรับวิธีการในตัวหรือไม่ แต่ถ้าคุณเพิ่มส่วนขยายของคุณเองเพื่อพูดว่า String.prototype คุณจะได้รับวัตถุสตริงเวอร์ชันบรรจุกล่องทุกครั้งที่เรียก
เบ็น

17

ในกรณีของสตริงลิเทอรัลเราไม่สามารถกำหนดคุณสมบัติได้

var x = "hello" ;
x.y = "world";
console.log(x.y); // this will print undefined

ในขณะที่ในกรณีของ String Object เราสามารถกำหนดคุณสมบัติได้

var x = new String("hello");
x.y = "world";
console.log(x.y); // this will print world

1
ในที่สุดก็มีคนกระตุ้นว่าทำไมเราถึงต้องการStringวัตถุเช่นกัน ขอบคุณ!
Ciprian Tomoiagă

1
ทำไมทุกคนต้องทำเช่นนี้?
Aditya

11

ตัวอักษรสตริง:

ตัวอักษรสตริงไม่เปลี่ยนรูปซึ่งหมายความว่าเมื่อสร้างแล้วจะไม่สามารถเปลี่ยนสถานะได้ซึ่งทำให้เธรดปลอดภัยเช่นกัน

var a = 's';
var b = 's';

a==b ผลลัพธ์จะเป็น 'จริง' ทั้งสองสตริงอ้างอิงวัตถุเดียวกัน

วัตถุสตริง:

ที่นี่มีการสร้างวัตถุสองชิ้นที่แตกต่างกันและมีการอ้างอิงต่างกัน:

var a = new String("s");
var b = new String("s");

a==b ผลลัพธ์จะเป็นเท็จเนื่องจากมีการอ้างอิงที่แตกต่างกัน


1
สตริงวัตถุไม่เปลี่ยนรูปด้วยหรือไม่?
Yang Wang

@YangWang ที่เป็นภาษาโง่ทั้งaและbพยายามที่จะกำหนดa[0] = 'X'มันจะถูกดำเนินการประสบความสำเร็จ แต่จะไม่ทำงานในขณะที่คุณอาจคาดหวัง
RUX

คุณเขียนว่า "var a = 's'; var b = 's'; a == b ผลลัพธ์จะเป็น 'true' ทั้งสองสตริงอ้างถึงวัตถุเดียวกัน" ไม่ถูกต้อง: a และ b ไม่อ้างถึงออบเจ็กต์เดียวกันผลลัพธ์เป็นจริงเพราะมีค่าเท่ากัน ค่าเหล่านี้จะถูกเก็บไว้ในตำแหน่งหน่วยความจำที่แตกต่างกันนั่นเป็นเหตุผลว่าทำไมถ้าคุณเปลี่ยนค่าเหล่านั้นจะไม่เปลี่ยน!
SC1000

9

ถ้าคุณใช้newคุณอย่างชัดเจนระบุว่าคุณต้องการที่จะสร้างตัวอย่างของนักการวัตถุ ดังนั้นจึงnew Stringมีการสร้างObject ที่ห่อหุ้มStringแบบดั้งเดิมซึ่งหมายความว่าการกระทำใด ๆ กับการทำงานนั้นเกี่ยวข้องกับเลเยอร์พิเศษของงาน

typeof new String(); // "object"
typeof '';           // "string"

ขณะที่พวกเขาเป็นประเภทที่แตกต่างกันของJavaScriptล่ามอาจเพิ่มประสิทธิภาพของพวกเขาแตกต่างกันตามที่กล่าวไว้ในความคิดเห็น


5

เมื่อคุณประกาศ:

var s = '0123456789';

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

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


มาได้อย่างไรสตริงสืบทอดดั้งเดิมทุกคุณสมบัติต้นแบบที่กำหนดเองรวมทั้งString.prototypeคน?
Yuriy Galanter

1
var s = '0123456789';เป็นค่าดั้งเดิมค่านี้มีวิธีได้อย่างไรผมงง!
The Alpha

2
@SheikhHeera - ภาษาดั้งเดิมถูกสร้างขึ้นในการใช้ภาษาเพื่อให้ล่ามสามารถให้พลังพิเศษแก่พวกเขาได้
jfriend00

1
@SheikhHeera - ฉันไม่เข้าใจความคิดเห็น / คำถามล่าสุดของคุณ สตริงดั้งเดิมโดยตัวมันเองไม่สนับสนุนให้คุณเพิ่มคุณสมบัติของคุณเองเข้าไป เพื่อที่จะอนุญาตสิ่งนั้นจาวาสคริปต์ยังมีอ็อบเจกต์ String ซึ่งมีวิธีการเดียวกันกับสตริงดั้งเดิม แต่เป็นอ็อบเจกต์แบบเต็มรูปแบบที่คุณสามารถปฏิบัติเหมือนอ็อบเจกต์ได้ทุกวิธี รูปแบบคู่นี้ดูเหมือนจะยุ่งเล็กน้อย แต่ฉันสงสัยว่ามันถูกทำให้ประสิทธิภาพลดลงเนื่องจากเคส 99% เป็นการใช้แบบดั้งเดิมและอาจเร็วกว่าและมีประสิทธิภาพหน่วยความจำมากกว่าวัตถุสตริง
jfriend00

1
@SheikhHeera "แปลงเป็นสตริง Object" เป็นวิธีที่ MDN แสดงออกเพื่ออธิบายว่าไพรมารีส์สามารถเรียกใช้เมธอดได้อย่างไร พวกเขาไม่ได้แปลงเป็นวัตถุสตริงอย่างแท้จริง
FabrícioMatté

4

ฉันเห็นว่าคำถามนี้ได้รับการแก้ไขเมื่อนานมาแล้วมีความแตกต่างที่ลึกซึ้งอีกอย่างระหว่างตัวอักษรสตริงและอ็อบเจ็กต์สตริงเนื่องจากดูเหมือนว่าไม่มีใครแตะต้องมันฉันคิดว่าฉันแค่เขียนมันเพื่อความสมบูรณ์

โดยทั่วไปความแตกต่างระหว่างทั้งสองคือเมื่อใช้ eval eval ('1 + 1') ให้ 2 ในขณะที่ eval (สตริงใหม่ ('1 + 1')) ให้ '1 + 1' ดังนั้นหากบล็อกโค้ดบางส่วนสามารถดำเนินการได้ทั้ง 'ปกติ' หรือด้วย eval ก็สามารถทำได้ นำไปสู่ผลลัพธ์ที่แปลกประหลาด


ขอบคุณสำหรับข้อมูลของคุณ :-)
The Alpha

ว้าวพฤติกรรมแปลก ๆ คุณควรเพิ่มการสาธิตในบรรทัดเล็ก ๆ ในความคิดเห็นของคุณเพื่อแสดงพฤติกรรมนี้ - เป็นการเปิดหูเปิดตามาก
EyuelDK

นี่เป็นเรื่องปกติถ้าคุณคิดเกี่ยวกับเรื่องนี้ new String("")ส่งคืนออบเจ็กต์และประเมินเฉพาะสตริงและส่งคืนทุกอย่างเหมือนเดิม
Félix Brunet

3

การมีอยู่ของอ็อบเจ็กต์นั้นไม่เกี่ยวข้องกับพฤติกรรมจริงของ String ในเอ็นจิ้น ECMAScript / JavaScript เนื่องจากขอบเขตรูทจะมีอ็อบเจ็กต์ฟังก์ชันสำหรับสิ่งนี้ ดังนั้นฟังก์ชัน charAt (int) ในกรณีของสตริงลิเทอรัลจะถูกค้นหาและดำเนินการ

ด้วยออบเจ็กต์จริงคุณจะเพิ่มอีกหนึ่งเลเยอร์ซึ่งเมธอด charAt (int) จะถูกค้นหาบนอ็อบเจ็กต์ด้วยก่อนที่พฤติกรรมมาตรฐานจะเริ่มทำงาน (เช่นเดียวกับด้านบน) เห็นได้ชัดว่ามีงานจำนวนมากที่ทำในกรณีนี้อย่างน่าประหลาดใจ

BTW ฉันไม่คิดว่า primitives จะถูกแปลงเป็น Objects แต่จริงๆแล้ว script engine จะทำเครื่องหมายตัวแปรนี้เป็นประเภทสตริงดังนั้นจึงสามารถค้นหาฟังก์ชันที่มีให้ทั้งหมดเพื่อให้ดูเหมือนว่าคุณเรียกใช้วัตถุ อย่าลืมว่านี่คือรันไทม์ของสคริปต์ซึ่งทำงานบนหลักการที่แตกต่างจากรันไทม์ OO


3

ความแตกต่างที่ใหญ่ที่สุดระหว่างสตริงดั้งเดิมและสตริงอ็อบเจ็กต์คืออ็อบเจ็กต์ต้องเป็นไปตามกฎนี้สำหรับตัว==ดำเนินการ :

นิพจน์เปรียบเทียบ Objects จะเป็นจริงก็ต่อเมื่อตัวถูกดำเนินการอ้างอิง Object เดียวกัน

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

"hello" == "hello"
-> true
new String("hello") == new String("hello") // beware!
-> false

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


ขอบคุณสำหรับการเพิ่มมูลค่าให้กับคำถามหลังจากผ่านไปค่อนข้างนาน :-)
The Alpha

1

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

บล็อก 1 เร็วกว่าส่วนใหญ่เนื่องจาก: var s = '0123456789'; เร็วกว่า var s = สตริงใหม่เสมอ ('0123456789'); เนื่องจากค่าใช้จ่ายในการสร้างวัตถุ

ส่วนการวนซ้ำไม่ใช่ส่วนที่ทำให้เกิดการชะลอตัวเนื่องจาก chartAt () สามารถอินไลน์ได้โดยล่าม ลองลบลูปออกแล้วรันการทดสอบอีกครั้งคุณจะเห็นว่าอัตราส่วนความเร็วจะเท่ากับถ้าไม่ได้เอาลูปออก กล่าวอีกนัยหนึ่งสำหรับการทดสอบเหล่านี้บล็อกลูปในเวลาดำเนินการมีรหัส bytecode / เครื่องเดียวกันทุกประการ

สำหรับการเปรียบเทียบขนาดเล็กประเภทนี้การดูที่ bytecode หรือรหัสเครื่องจะให้ภาพที่ชัดเจนขึ้น


1
ขอบคุณสำหรับคำตอบ.
The Alpha

0

ใน Javascript ชนิดข้อมูลดั้งเดิมเช่นสตริงเป็นแบบเอกสารสำเร็จรูปที่ไม่ใช่คอมโพสิต ซึ่งหมายความว่าเป็นเพียงค่านิยมไม่มีอะไรเพิ่มเติม: let a = "string value"; โดยค่าเริ่มต้นไม่มีเมธอดในตัวเช่น toUpperCase, toLowerCase และอื่น ๆ ...

แต่ถ้าคุณพยายามเขียน:

console.log( a.toUpperCase() ); or console.log( a.toLowerCase() );

สิ่งนี้จะไม่ทำให้เกิดข้อผิดพลาดใด ๆ แต่จะทำงานตามที่ควรจะเป็น

เกิดอะไรขึ้น ? เมื่อคุณพยายามเข้าถึงคุณสมบัติของสตริงaJavascript บีบบังคับสตริงให้กับอ็อบเจ็กต์โดยnew String(a);รู้จักกันในชื่อwrapper objectวัตถุที่ห่อหุ้ม

กระบวนการนี้เชื่อมโยงกับแนวคิดที่เรียกว่าตัวสร้างฟังก์ชันใน Javascript ซึ่งฟังก์ชันจะถูกใช้เพื่อสร้างวัตถุใหม่

เมื่อคุณพิมพ์new String('String value');ที่นี่ String คือตัวสร้างฟังก์ชันซึ่งรับอาร์กิวเมนต์และสร้างวัตถุว่างภายในขอบเขตฟังก์ชันวัตถุว่างนี้จะถูกกำหนดให้กับสิ่งนี้และในกรณีนี้ String จะให้สิ่งที่รู้จักในตัวฟังก์ชันที่เรากล่าวถึงก่อนหน้านี้ และทันทีที่การดำเนินการเสร็จสิ้นตัวอย่างเช่นการดำเนินการตัวพิมพ์ใหญ่วัตถุที่ห่อหุ้มจะถูกทิ้ง

เพื่อพิสูจน์ว่าลองทำสิ่งนี้:

let justString = 'Hello From String Value';
justString.addNewProperty = 'Added New Property';
console.log( justString );

ผลลัพธ์ที่นี่จะไม่ได้กำหนดไว้ ทำไม? ในกรณีนี้ Javascript จะสร้างออบเจ็กต์ Wrapper String ตั้งค่าคุณสมบัติใหม่addNewPropertyและละทิ้งอ็อบเจ็กต์ wrapper ทันที นี่คือเหตุผลที่คุณไม่ได้กำหนด รหัสเทียมจะมีลักษณะดังนี้:

let justString = 'Hello From String Value';
let wrapperObject = new String( justString );
wrapperObject.addNewProperty = 'Added New Property'; //Do operation and discard

0

เราสามารถกำหนด String ได้ 3 วิธี

  1. var a = "วิธีแรก";
  2. var b = String ("ทางที่สอง");
  3. var c = สตริงใหม่ ("วิธีที่สาม");

// นอกจากนี้เราสามารถสร้างโดยใช้ 4. var d = a + '';

ตรวจสอบประเภทของสตริงที่สร้างโดยใช้ตัวดำเนินการ typeof

  • พิมพ์ // "string"
  • พิมพ์ b // "สตริง"
  • typeof c // "วัตถุ"


เมื่อคุณเปรียบเทียบ a และ b var a==b ( // yes)


เมื่อคุณเปรียบเทียบวัตถุสตริง

var StringObj = new String("third way")
var StringObj2 = new String("third way")
StringObj  == StringObj2 // no result will be false, because they have different references
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.