เหตุใดผลลัพธ์จึงแตกต่างกันไปตามตำแหน่งปีกกา


119

เหตุใดข้อมูลโค้ดด้านล่างซึ่งนำมาจากบทความนี้จึงให้ผลลัพธ์ที่แตกต่างกันเนื่องจากการเปลี่ยนแปลงตำแหน่งของวงเล็บปีกกาเพียงครั้งเดียว

เมื่อวงเล็บปีกกาเปิด{อยู่ในบรรทัดใหม่test()จะแสดงundefinedและ "ไม่ - มันพัง: ไม่ได้กำหนด" ในการแจ้งเตือน

function test()
{
  return
  { /* <--- curly brace on new line */
    javascript: "fantastic"
  };
}

var r = test();
try {
  alert(r.javascript); // does this work...?
} catch (e) {
  alert('no - it broke: ' + typeof r);
}

เมื่อรั้งอยู่ในสายเดียวกับreturn, test()ผลตอบแทนที่วัตถุและ "มหัศจรรย์" จะรับการแจ้งเตือน

function test()
{
  return { /* <---- curly brace on same line */
    javascript: "fantastic"
  };
}

var r = test();
try {
  alert(r.javascript); // does this work...?
} catch (e) {
  alert('no - it broke: ' + typeof r);
}


ความหมายกึ่งแทรกหลังreturnแตกต่างจากที่อื่นเล็กน้อยและเส้นแบ่ง "หมายถึง" ในจุดนั้นมากกว่าที่จะเป็น "กลางคัน"
dandavis

คำตอบ:


165

นั่นคือหนึ่งในข้อผิดพลาดของ JavaScript: การแทรกอัฒภาคอัตโนมัติ บรรทัดที่ไม่ได้ลงท้ายด้วยอัฒภาค แต่อาจเป็นจุดสิ้นสุดของคำสั่งจะถูกยกเลิกโดยอัตโนมัติดังนั้นตัวอย่างแรกของคุณจึงมีลักษณะดังนี้:

function test()
{
  return; // <- notice the inserted semicolon
  { 
    javascript: "fantastic"
  };
}

ดูคู่มือสไตล์ JS ของ Douglas Crockfordซึ่งกล่าวถึงการแทรกอัฒภาค

ในตัวอย่างที่สองของคุณคุณส่งคืนวัตถุ (สร้างโดยวงเล็บปีกกา) ด้วยคุณสมบัติjavascriptและมูลค่าของ"fantastic"มันอย่างมีประสิทธิภาพเช่นนี้:

function test() {
    var myObject = new Object();
    myObject.javascript = "fantastic";
    return myObject;
}

5
เรื่องน่ารู้: ในเครื่องมือบางอย่างคุณสามารถแสดงความคิดเห็นเกี่ยวกับอัฒภาคที่แทรกอัตโนมัติได้
Christopher Tarquini

1
@ChrisT: อะไรนะ? อันไหน? นี่สำรวจที่ไหน
Sean McMillan

1
@SeanMcMillan ฉันได้อ่านบทความเกี่ยวกับเรื่องนี้แล้ว แต่ดูเหมือนจะไม่พบบทความใด ๆ จากการค้นหาอย่างรวดเร็ว ฉันจำได้ว่าการใส่return /*แล้ว*/{ จะแสดงความคิดเห็นเกี่ยวกับเซมิโคลอนที่ซ่อนอยู่ใน Chrome เวอร์ชันเก่าได้อย่างมีประสิทธิภาพ ไม่แน่ใจว่ายังใช้ได้อยู่หรือเปล่า
Christopher Tarquini

2
เพราะนิสัยแปลก ๆ เหล่านี้ทำให้ฉันสัญญากับตัวเองเมื่อ 10 ปีก่อน: อยู่ห่าง ๆ จากเว็บ! ฉันภาวนาให้ Interwebs จางหายไป ... น่าเสียดายที่มันไม่เป็นไปตามแผนและตอนนี้ฉันก็ต้องต่อสู้กับปัญหาเหล่านี้เช่นกัน Karma is ab * tch :)
Jowen

1
ฉันเคยเห็นคนที่นับถือศาสนากับอัฒภาคใน JavaScript ฉันเคยสงสัยเสมอว่าพวกเขาทำอะไรกับช่วงเวลาพิเศษที่พวกเขาประหยัดได้โดยไม่ใส่เครื่องหมายอัฒภาค
Iman Mohamadi

9

Javascript ไม่ต้องการเครื่องหมายอัฒภาคในตอนท้ายของข้อความสั่ง แต่ข้อเสียคือต้องเดาว่าอัฒภาคอยู่ที่ไหน ส่วนใหญ่แล้วสิ่งนี้ไม่ใช่ปัญหา แต่บางครั้งมันก็สร้างอัฒภาคโดยที่คุณไม่ได้ตั้งใจ

ตัวอย่างจากบล็อกโพสต์ของฉันเกี่ยวกับเรื่องนี้ ( Javascript - แทบไม่อิงบรรทัด ):

หากคุณจัดรูปแบบโค้ดดังนี้:

function getAnswer() {
   var answer = 42;
   return
      answer;
}

จากนั้นจะตีความเช่นนี้:

function getAnswer() {
  var answer = 42;
  return;
  answer;
}

คำสั่ง return อยู่ในรูปแบบที่ไม่มีพารามิเตอร์และอาร์กิวเมนต์จะกลายเป็นคำสั่งของตัวมันเอง

เช่นเดียวกันกับรหัสของคุณ ฟังก์ชันถูกตีความว่า:

function test()
{
  return;
  {
    javascript : "fantastic"
  };
}

3

โดยส่วนตัวแล้วฉันชอบสไตล์ Allman เพื่อความสามารถในการอ่าน (เทียบกับสไตล์ K&R)

แทน…

function test() {
  return {
    javascript : "fantastic"
  };
}

ฉันชอบ…

function test() 
{
  var obj =
  {
    javascript : "fantastic"
  };

  return obj;
}

แต่นี่เป็นวิธีแก้ปัญหา ฉันสามารถอยู่กับมันได้


3
ฉันคิดว่าเราควรหลีกเลี่ยงความชอบส่วนตัวที่เบี่ยงเบนไปจากกระแสหลัก เราควรทำตามทางเลือกของคนส่วนใหญ่ซึ่งส่งเสริมความสม่ำเสมอซึ่งจะช่วยเพิ่มความสามารถในการอ่าน
Jowen

1
ฉันพบว่ารหัสของเขาอ่านได้ง่ายกว่า K&R ค่อนข้างเป็นส่วนตัวเมื่อคุณหมายถึง "อ่านได้"
รำ

ฉันชอบ Allman เหมือนกัน ... แต่เนื่องจาก ASI เมื่อฉันต้องการส่งคืนวัตถุฉันจึงปล่อยให้กึ่งอยู่ในบรรทัดเดียวกับการส่งคืน ฉันชอบสิ่งนี้มากกว่าที่จะเพิ่ม "var x =" หนึ่งบรรทัด ...
Mik

1

เป็นเพราะจาวาสคริปต์มักใส่ ";" ในตอนท้ายของแต่ละบรรทัดดังนั้นโดยพื้นฐานแล้วเมื่อคุณกลับมา {ในบรรทัดเดียวกันเอ็นจิ้น javascript จะเห็นว่าจะมีอะไรมากกว่านั้นและเมื่ออยู่ในบรรทัดใหม่มันคิดว่าคุณลืมใส่ ";" และวางไว้ให้คุณ


1
ฉันไม่เข้าใจว่าทำไมคำตอบของ cichy, Darin และ Ivo จึงถูกลงคะแนน?
BoltClock

1

วงเล็บปีกกาที่นี่บ่งบอกถึงการสร้างวัตถุใหม่ ดังนั้นรหัสของคุณจึงเทียบเท่ากับ:

function test() {
  var a = { javascript : "fantastic" };
  return a;
}

ซึ่งใช้งานได้ในขณะที่คุณเขียน:

function test() {
  var a = { javascript : "fantastic" };
  return; // ; is automatically inserted 
      a;
}

มันไม่ทำงานอีกต่อไป


0

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


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