Pertanyaan asosiatif “Tidak Tertangkap TypeError: objek bukan fungsi” Javascript

95

Kode adalah sebagai berikut:

<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>

Ini akan melempar:

"Tidak Tertangkap TypeError: objek bukan fungsi"

Jika saya membungkus pemanggilan / pemanggilan fungsi anonim dalam kumpulan tanda kurung lain, itu akan menjalankan peringatan, tetapi masih memberi saya kesalahan. Jika saya meletakkan titik koma setelah definisi "var postTypes" maka itu akan baik-baik saja.

Saya dituntun untuk percaya bahwa javascript tidak memerlukan titik koma, jadi saya menebak bahwa ada beberapa aturan asosiasi aneh dari aplikasi fungsi yang saya tidak sepenuhnya mengerti. Mengapa saya mendapatkan kesalahan ini?

PolandiaSpring
sumber
Sepertinya Anda mencoba membuat fungsi anonim dan fungsi statis dan mengharapkannya untuk dieksekusi sebagai satu. Apa yang terjadi jika Anda menghapus function ()
brumScouse

Jawaban:

88

JavaScript memang membutuhkan titik koma, hanya saja penerjemah akan memasukkannya untuk Anda pada jeda baris jika memungkinkan * .

Sayangnya, kodenya

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

tidak tidak menghasilkan kesalahan sintaks, sehingga tidak ada ;akan dimasukkan. (Contoh yang bisa dijalankan adalah

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

Untuk menghindari kejutan seperti ini, latih diri Anda untuk selalu mengakhiri pernyataan dengan ;.


* Ini hanyalah aturan praktis dan tidak selalu benar. Aturan penyisipan jauh lebih rumit. Ini halaman blog tentang penyisipan titik koma memiliki lebih rinci.

kennytm
sumber
13
Atau: Untuk menghindari kejutan seperti ini, latih diri Anda untuk menulis kode yang dapat dibaca dengan bersih (yang harus selalu berlaku) dan ketahui aturan ASI umum ... itu sebenarnya tidak berbeda dengan "mengetahui" cara kerja closure di JS.
18

Kode Anda mengalami kasus di mana proses Penyisipan Titik Koma Otomatis (ASI) tidak terjadi.

Anda tidak boleh mengandalkan ASI. Anda harus menggunakan titik koma untuk memisahkan pernyataan dengan benar:

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

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

Kode Anda sebenarnya mencoba memanggil objek array.

Christian C. Salvadó
sumber
Salah satu cara untuk memperbaiki masalah ini, tapi saya tidak bisa berada di belakang klub Crockford.
1
@pst: Mari saya ulangi, saya tidak dalam Crock's-klub sama sekali :)
Christian C. Salvado
Dalam hal ini saya minta maaf atas kata-kata kasar :(
Saya menikmati kuisnya. ASI memang sangat membingungkan dengan kode icky!
8

Saya mendapat kesalahan serupa dan butuh beberapa saat untuk menyadari bahwa dalam kasus saya, saya menamai variabel array payInvoices dan fungsinya juga payInvoices. Itu membingungkan AngularJs. Setelah saya mengubah nama menjadi processPayments () akhirnya berhasil. Hanya ingin membagikan kesalahan dan solusi ini karena saya butuh waktu lama untuk mengetahuinya.

Naomi
sumber
Sama di sini, saya memiliki variabel bernama alertdan mencoba memanggil fungsi peringatan javascript dan akan mengatakan 'peringatan bukan fungsi'. Itu mencoba memanggil alertvariabel alih-alih fungsi sebenarnya
James111
0

Cobalah untuk memiliki badan fungsi sebelum pemanggilan fungsi dalam file JavaScript Anda.

CMPE
sumber
0

Saya mendapatkan kesalahan yang sama dan menghabiskan satu setengah hari mencoba menemukan solusi. Jawaban Naomi menuntun saya pada solusi yang saya butuhkan.

Masukan saya (type = button) memiliki atribut nameyang identik dengan nama fungsi yang dipanggil oleh acara onClick. Setelah saya mengubah atribut namesemuanya bekerja.

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

diubah menjadi:

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

Saya mengalami kesalahan ini saat menyusun dan memaketkan TS dengan WebPack. Ini mengkompilasi export class AppRouterElement extends connect(store, LitElement){....}menjadi let Sr = class extends (Object(wr.connect) (fn, vr)) {....}yang tampaknya salah karena hilang koma. Saat memaketkan dengan Rollup, tidak ada kesalahan.

Dzintars
sumber