สิ่งสำคัญคือต้องเข้าใจว่าตัว=
ดำเนินการใน JavaScript ทำและไม่ทำอะไร
=
ผู้ประกอบการไม่ได้ทำให้สำเนาของข้อมูล
ตัว=
ดำเนินการสร้างการอ้างอิงใหม่ไปยังข้อมูลเดียวกัน
หลังจากที่คุณเรียกใช้รหัสเดิมของคุณ:
var a = $('#some_hidden_var').val(),
b = a;
a
และb
ตอนนี้สองชื่อแตกต่างกันสำหรับวัตถุเดียวกัน
การเปลี่ยนแปลงใด ๆ ที่คุณทำกับเนื้อหาของวัตถุนี้จะเห็นเหมือนกันไม่ว่าคุณจะอ้างอิงผ่านa
ตัวแปรหรือb
ตัวแปร เป็นวัตถุเดียวกัน
ดังนั้นเมื่อคุณพยายาม "เปลี่ยนกลับ" b
เป็นa
วัตถุดั้งเดิมในภายหลังด้วยรหัสนี้:
b = a;
รหัสไม่ได้ทำอะไรเลยเพราะa
และb
เป็นสิ่งเดียวกัน รหัสจะเหมือนกับที่คุณเขียน:
b = b;
ซึ่งเห็นได้ชัดว่าจะไม่ทำอะไรเลย
เหตุใดรหัสใหม่ของคุณจึงใช้งานได้
b = { key1: a.key1, key2: a.key2 };
ที่นี่คุณกำลังสร้างออบเจ็กต์ใหม่เอี่ยมด้วย{...}
อ็อบเจกต์ลิเทอรัล วัตถุใหม่นี้ไม่เหมือนกับวัตถุเก่าของคุณ ตอนนี้คุณกำลังตั้งค่าb
ให้อ้างอิงถึงวัตถุใหม่นี้ซึ่งจะทำสิ่งที่คุณต้องการ
เพื่อจัดการกับวัตถุใด ๆ โดยพลคุณสามารถใช้ฟังก์ชั่นการโคลนวัตถุดังกล่าวเป็นหนึ่งที่ระบุไว้ในคำตอบของอาร์มันด์หรือตั้งแต่คุณใช้ jQuery เพียงแค่ใช้ฟังก์ชั่น$.extend()
ฟังก์ชันนี้จะสร้างสำเนาตื้นหรือสำเนาลึกของวัตถุ (อย่าสับสนกับ$().clone()
วิธีนี้สำหรับการคัดลอกองค์ประกอบ DOM ไม่ใช่วัตถุ)
สำหรับสำเนาตื้น:
b = $.extend( {}, a );
หรือสำเนาลึก:
b = $.extend( true, {}, a );
สำเนาตื้นกับสำเนาลึกต่างกันอย่างไร สำเนาตื้นจะคล้ายกับรหัสของคุณที่สร้างวัตถุใหม่ด้วยตัวอักษรของวัตถุ สร้างอ็อบเจ็กต์ระดับบนสุดใหม่ที่มีการอ้างอิงถึงคุณสมบัติเดียวกันกับอ็อบเจ็กต์ดั้งเดิม
หากออบเจ็กต์ของคุณมีเฉพาะประเภทดั้งเดิมเช่นตัวเลขและสตริงสำเนาลึกและสำเนาตื้นจะทำสิ่งเดียวกันทุกประการ แต่ถ้าวัตถุของคุณมีวัตถุหรืออาร์เรย์อื่น ๆ ที่ซ้อนอยู่ภายในสำเนาตื้น ๆ จะไม่คัดลอกวัตถุที่ซ้อนกันเหล่านั้นเพียงสร้างการอ้างอิงถึงวัตถุเหล่านั้น ดังนั้นคุณอาจมีปัญหาเดียวกันกับวัตถุซ้อนที่คุณมีกับวัตถุระดับบนสุดของคุณ ตัวอย่างเช่นให้วัตถุนี้:
var obj = {
w: 123,
x: {
y: 456,
z: 789
}
};
หากคุณทำสำเนาวัตถุนั้นแบบตื้นx
คุณสมบัติของวัตถุใหม่ของคุณจะเป็นx
วัตถุเดียวกันจากต้นฉบับ:
var copy = $.extend( {}, obj );
copy.w = 321;
copy.x.y = 654;
ตอนนี้วัตถุของคุณจะมีลักษณะดังนี้:
var copy = {
w: 321,
x: {
y: 654,
z: 789
}
};
var obj = {
w: 123,
x: {
y: 654,
z: 789
}
};
คุณสามารถหลีกเลี่ยงสิ่งนี้ได้ด้วยสำเนาลึก สำเนาแบบลึกจะวนซ้ำในทุกออบเจ็กต์และอาร์เรย์ที่ซ้อนกัน (และวันที่ในรหัสของ Armand) เพื่อทำสำเนาของวัตถุเหล่านั้นในลักษณะเดียวกับที่ทำสำเนาของวัตถุระดับบนสุด ดังนั้นการเปลี่ยนแปลงcopy.x.y
จะไม่ส่งผลกระทบobj.x.y
จะไม่ส่งผลกระทบต่อ
คำตอบสั้น ๆ : หากมีข้อสงสัยคุณอาจต้องการสำเนาแบบละเอียด
a
ตั้งค่าจากที่.val()
ฉันถือว่าเป็น JSON (สตริง) ไม่ใช่วัตถุ - ใช่ไหม คุณใช้JSON.parse(a)
ในบางจุดเพื่อรับวัตถุจริงหรือไม่?