การทำลายโครงสร้างโดยไม่ต้องแปรผัน


102

เหตุใดการทำลายโครงสร้างวัตถุจึงทำให้เกิดข้อผิดพลาดหากไม่มีvarคีย์เวิร์ดอยู่ข้างหน้า

{a, b} = {a: 1, b: 2};

พ่น SyntaxError: expected expression, got '='

สามตัวอย่างต่อไปนี้ใช้งานได้โดยไม่มีปัญหา

var {a, b} = {a: 1, b: 2};
var [c, d] = [1, 2];
    [e, f] = [1, 2];

คำถามโบนัส: ทำไมเราไม่จำเป็นต้องมีvarการทำลายโครงสร้างอาร์เรย์?

ฉันพบปัญหาในการทำสิ่งที่ชอบ

function () {
  var {a, b} = objectReturningFunction();

  // Now a and b are local variables in the function, right?
  // So why can't I assign values to them?

  {a, b} = objectReturningFunction();
}

คำตอบ:


163

ปัญหาเกิดจากตัว{...}ดำเนินการที่มีหลายความหมายใน JavaScript

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

สิ่งนี้varช่วยสร้างความแตกต่างเนื่องจากไม่สามารถตามด้วยคำชี้แจงได้ตามที่จะจัดกลุ่มวงเล็บ :

( {a, b} = objectReturningFunction() );

จากเอกสารของพวกเขา: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Assignment_without_declaration

หมายเหตุ: จำเป็นต้องใช้วงเล็บ (... ) รอบคำสั่งการกำหนดเมื่อใช้การกำหนดโครงสร้างการทำลายอ็อบเจ็กต์โดยไม่ต้องประกาศ

{a, b} = {a: 1, b: 2} ไม่ใช่ไวยากรณ์แบบสแตนด์อะโลนที่ถูกต้องเนื่องจาก {a, b} ทางด้านซ้ายถือเป็นบล็อกและไม่ใช่ตัวอักษรของวัตถุ

อย่างไรก็ตาม ({a, b} = {a: 1, b: 2}) นั้นถูกต้องเช่นเดียวกับ var {a, b} = {a: 1, b: 2}

นิพจน์ (... ) ของคุณต้องนำหน้าด้วยอัฒภาคหรืออาจใช้เพื่อเรียกใช้ฟังก์ชันในบรรทัดก่อนหน้า


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

เคล็ดลับการจัดกลุ่มวงเล็บเป็นเคล็ดลับที่ดี
James Smith

นี่เป็นเกร็ดความรู้ที่คลุมเครือซึ่งทำให้ฉันนิ่งงัน ช่วยให้สามารถทำลายโครงสร้างข้ามขอบเขตได้ (แน่นอนว่าคุณยังต้องประกาศตัวแปรของคุณ) แต่มันช่วยแก้ข้อ จำกัด ของการใช้ Promise Chains ในขณะที่ต้องใช้ตัวแปรหลายตัวที่แก้ไขจากขั้นตอนหนึ่งของ Promise chain ในอีกขั้นหนึ่งโดยไม่สร้างความยุ่งเหยิงมากเกินไป ขอบคุณ.
Kevin Teljeur

27

หากคุณเขียน Javascript โดยไม่มีเครื่องหมายอัฒภาคไวยากรณ์ "การกำหนดโดยไม่มีการประกาศ" ควรนำหน้าด้วยอัฒภาคเพื่อให้สามารถคาดเดาได้

let a, b

;({a, b} = objectReturningFunction()) // <-- note the preceding ;

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

อันที่จริงมันอยู่ตรงนั้นในคำตอบที่ยอมรับ (บรรทัดสุดท้ายของเอกสารที่ยกมา) แต่พลาดง่ายโดยเฉพาะเมื่อไม่เห็นตัวอย่าง!


2
ใช่. เหตุผลที่ผู้คนต้องใช้เครื่องหมายทวิภาค!
jfriend00

2

นี่เป็นอีกวิธีหนึ่ง:

let {} = {a, b} = objectReturningFunction()

ข้อดี:

  • ไม่จำเป็นต้องมีวงเล็บ
  • ไม่จำเป็นต้องใช้อัฒภาค
  • การมอบหมายงานพิเศษเป็นการรับประกันว่าจะไม่มีการดำเนินการใด ๆ (เนื่องจากไม่มีสิ่งแปลก ๆ เกิดขึ้น)

จุดด้อย:

  • ลักษณะบิตแปลกแม้ว่าในความคิดของฉันไม่ประหลาดกว่าIIFE!(){...}()
  • อาจจะงงว่าทำไมถึงมี รับประกันได้ว่าจะทำให้ผู้คนไม่พอใจในการเผชิญหน้าครั้งแรกดังนั้นฉันขอแนะนำไม่ให้ใช้เป็นการครั้งเดียว

ชนิดของความรู้สึกเหมือนของ IIFE จะเปรียบมากขึ้นเพื่อกว่า;({ a, b }) let {} = { ... }เคล็ดลับที่ดีแม้ว่า :)
shuckster

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