Javascript“ Uncaught TypeError: object is not a function” Associativity question


95

รหัสมีดังนี้:

<body>
    <a href="javascript:;" id="test">hello</a>
</body>

<script type="text/javascript">
    document.getElementById("test").addEventListener("click", function () {
      test()
    }, false)
    function test() {
      var postTypes = new Array('hello', 'there')   
      (function() { alert('hello there') })()
    }
</script>

สิ่งนี้จะทำให้เกิด:

"Uncaught TypeError: object ไม่ใช่ฟังก์ชัน"

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

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


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

คำตอบ:


88

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

ขออภัยรหัส

var a = new B(args)(stuff)()

ไม่ได้ส่งผลให้เกิดข้อผิดพลาดทางไวยากรณ์จึงไม่มี;จะถูกแทรก (ตัวอย่างที่รันได้คือ

var answer = new Function("x", "return x")(function(){return 42;})();

เพื่อหลีกเลี่ยงความประหลาดใจเช่นนี้ฝึกตัวเองให้จบประโยคด้วย;เสมอ


*นี่เป็นเพียงกฎทั่วไปและไม่เป็นความจริงเสมอไป กฎการแทรกนั้นซับซ้อนกว่ามาก นี้หน้าบล็อกเกี่ยวกับการแทรกอัฒภาคมีรายละเอียดเพิ่มเติม


13
หรือ: เพื่อหลีกเลี่ยงความประหลาดใจเช่นนี้ฝึกตัวเองให้เขียนโค้ดที่อ่านได้สะอาด (ซึ่งควรใช้เสมอ) และรู้กฎ ASI ทั่วไป ... จริงๆแล้วมันไม่ต่างอะไรกับการ "รู้" ว่าการปิดใน JS ทำงานอย่างไร

18

โค้ดของคุณประสบกับกรณีที่กระบวนการแทรกอัฒภาคอัตโนมัติ (ASI) ไม่เกิดขึ้น

คุณไม่ควรพึ่งพา ASI คุณควรใช้อัฒภาคเพื่อแยกข้อความอย่างถูกต้อง:

var postTypes = new Array('hello', 'there'); // <--- Place a semicolon here!!

(function() { alert('hello there') })();

รหัสของคุณพยายามเรียกใช้วัตถุอาร์เรย์จริงๆ


วิธีหนึ่งในการแก้ไขปัญหา แต่ฉันไม่สามารถตามหลัง Crockford-club ได้

1
@pst: ให้ฉันเขียนใหม่ฉันไม่ได้อยู่ในสโมสรของ Crock เลย :)
Christian C. Salvadó

ในกรณีนี้ฉันต้องขออภัยสำหรับคำพูดที่รุนแรง :(

ฉันสนุกกับการตอบคำถาม ASI สับสนอย่างมากกับรหัสที่น่าเบื่อ!

8

ฉันได้รับข้อผิดพลาดที่คล้ายกันและฉันต้องใช้เวลาสักพักกว่าจะรู้ว่าในกรณีของฉันฉันตั้งชื่อตัวแปรอาร์เรย์ payInvoices และฟังก์ชันนี้ยัง payInvoices มันสับสน AngularJs เมื่อฉันเปลี่ยนชื่อเป็น processPayments () มันก็ใช้งานได้ในที่สุด แค่อยากจะแบ่งปันข้อผิดพลาดและวิธีแก้ปัญหานี้เนื่องจากฉันใช้เวลานานในการคิดออก


เหมือนกันที่นี่ฉันมีตัวแปรชื่อalertและพยายามเรียกใช้ฟังก์ชันการแจ้งเตือนจาวาสคริปต์และจะบอกว่า 'การแจ้งเตือนไม่ใช่ฟังก์ชัน' พยายามเรียกalertตัวแปรแทนฟังก์ชันจริง
James111

0

พยายามมีส่วนของฟังก์ชันก่อนการเรียกใช้ฟังก์ชันในไฟล์ JavaScript ของคุณ


0

ฉันได้รับข้อผิดพลาดเดียวกันนี้และใช้เวลาหนึ่งวันครึ่งในการพยายามหาทางแก้ไข คำตอบของนาโอมินำฉันไปสู่ทางออกที่ฉันต้องการ

อินพุตของฉัน (type = button) มีแอตทริบิวต์nameที่เหมือนกับชื่อฟังก์ชันที่ถูกเรียกโดยเหตุการณ์ onClick เมื่อฉันเปลี่ยนแอตทริบิวต์nameทุกอย่างทำงานได้

<input type="button" name="clearEmployer" onClick="clearEmployer();">

เปลี่ยนไปเป็น:

<input type="button" name="clearEmployerBtn" onClick="clearEmployer();">

0

ฉันมีข้อผิดพลาดนี้เมื่อรวบรวมและรวม TS กับ WebPack มันรวบรวมexport class AppRouterElement extends connect(store, LitElement){....}เข้าlet Sr = class extends (Object(wr.connect) (fn, vr)) {....}ซึ่งดูเหมือนว่าผิดเพราะของหายจุลภาค เมื่อรวมกับ Rollup ไม่มีข้อผิดพลาด

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