TypeError yang tidak tertangkap: (nilai antara) (…) bukan sebuah fungsi


128

Semuanya berfungsi dengan baik ketika saya menulis logika js dalam closure sebagai satu file js, seperti:

(function(win){
   //main logic here
   win.expose1 = ....
   win.expose2 = ....
})(window)

tetapi ketika saya mencoba memasukkan fungsi alternatif logging sebelum penutupan itu di file js yang sama,

 window.Glog = function(msg){
     console.log(msg)
 }
 // this was added before the main closure.

 (function(win){
   //the former closure that contains the main javascript logic;
 })(window)

itu mengeluh bahwa ada TypeError:

Uncaught TypeError: (intermediate value)(...) is not a function

Apa kesalahan yang telah aku perbuat?

Jawaban:


275

Kesalahan adalah hasil dari titik koma yang hilang di baris ketiga:

window.Glog = function(msg) {
  console.log(msg);
}; // <--- Add this semicolon

(function(win) {
  // ...
})(window);

Spesifikasi ECMAScript memiliki aturan khusus untuk penyisipan titik koma otomatis , namun dalam kasus ini titik koma tidak dimasukkan secara otomatis karena ekspresi dalam tanda kurung yang dimulai pada baris berikutnya dapat diartikan sebagai daftar argumen untuk pemanggilan fungsi.

Ini berarti bahwa tanpa titik koma tersebut, window.Glogfungsi anonim sedang dipanggil dengan fungsi sebagai msgparameter, diikuti dengan (window)yang kemudian mencoba untuk memanggil apapun yang dikembalikan.

Beginilah cara kode itu diinterpretasikan:

window.Glog = function(msg) {
  console.log(msg);
}(function(win) {
  // ...
})(window);

4
@armnotstrong Josh lebih cepat, dan jawabannya sama :)
mrlew

1
Terima kasih Pak! Linter saya menghapus titik koma secara otomatis dan semuanya rusak :)
Jonas Lomholdt

1
luar biasa !!! Terima kasih banyak!! Saya hampir kehilangan semua rambut saya karena yang satu ini ...
TMS

1
Ini, temanku, adalah emas!
LihO

1
ini gila dan saya sangat berterima kasih atas posting ini. Saya menyetel status setelah ifpernyataan dalam useEffect()fungsi React ketika saya terus menerima kesalahan "... bukan fungsi" ini.
Rahul Nath

7

Untuk membuat aturan titik koma menjadi sederhana

Setiap baris yang dimulai dengan (, [, `, atau operator manapun (/, +, - adalah satu-satunya yang sah), harus dimulai dengan titik koma.

func()
;[0].concat(myarr).forEach(func)
;(myarr).forEach(func)
;`hello`.forEach(func)
;/hello/.exec(str)
;+0
;-0

Ini mencegah a

func()[0].concat(myarr).forEach(func)(myarr).forEach(func)`hello`.forEach(func)/hello/.forEach(func)+0-0

keburukan.

Catatan Tambahan

Untuk menyebutkan apa yang akan terjadi: tanda kurung akan diindeks, tanda kurung akan diperlakukan sebagai parameter fungsi. Backtick akan berubah menjadi template yang diberi tag , dan regex atau integer yang ditandatangani secara eksplisit akan berubah menjadi operator. Tentu saja, Anda bisa menambahkan titik koma di akhir setiap baris. Ada baiknya untuk diingat ketika Anda dengan cepat membuat prototipe dan menghapus titik koma Anda.

Selain itu, menambahkan titik koma di akhir setiap baris tidak akan membantu Anda dalam hal berikut, jadi ingatlah pernyataan seperti

return // Will automatically insert semicolon, and return undefined.
    (1+2);
i // Adds a semicolon
   ++ // But, if you really intended i++ here, your codebase needs help.

Kasus di atas akan terjadi kembali / lanjutkan / putus / ++ / -. Setiap linter akan menangkap ini dengan kode mati atau kesalahan sintaks ++ / - (++ / - tidak akan pernah terjadi secara realistis).

Terakhir, jika Anda ingin penggabungan file berfungsi, pastikan setiap file diakhiri dengan titik koma. Jika Anda menggunakan program bundler (disarankan), program ini akan melakukannya secara otomatis.


5

Kasus Kesalahan:

var userListQuery = {
    userId: {
        $in: result
    },
    "isCameraAdded": true
}

( cameraInfo.findtext != "" ) ? searchQuery : userListQuery;

Keluaran:

TypeError: (intermediate value)(intermediate value) is not a function

Perbaiki: Anda kehilangan titik koma (;) untuk memisahkan ekspresi

userListQuery = {
    userId: {
        $in: result
    },
    "isCameraAdded": true
}; // Without a semi colon, the error is produced

( cameraInfo.findtext != "" ) ? searchQuery : userListQuery;

3

Bagi saya itu jauh lebih sederhana tetapi butuh beberapa saat untuk mengetahuinya. Kami pada dasarnya memiliki .jslib kami

some_array.forEach(item => {
    do_stuff(item);
});

Ternyata Unity (emscripten?) Tidak menyukai sintaks itu. Kami menggantinya dengan for-loop lama yang bagus dan langsung berhenti mengeluh. Aku benar-benar membencinya karena itu tidak menunjukkan baris yang dikeluhkannya, tapi bagaimanapun juga, membodohiku dua kali karena malu padaku.


Dugaan saya adalah bahwa masalah Anda ada hubungannya dengan ini
Brandito

Ini adalah kasus yang berbeda dari pertanyaannya.
CherryDT

@CherryDT tidak, karena kesalahan yang saya dapatkan adalah yang persis sama.
tfrascaroli

Tidak, pertanyaan ini adalah tentang kesalahan yang Anda peroleh karena tidak sengaja memanggil sesuatu sebagai fungsi karena tidak ada titik koma antara pernyataan dan a (di baris berikutnya. Saya tidak melihat semua itu dalam kasus Anda. Pertanyaannya bukan hanya judulnya!
CherryDT

1

Saya telah menghadapi masalah ini ketika saya membuat kelas ES2015 baru di mana nama properti sama dengan nama metode.

misalnya:

class Test{
  constructor () {
    this.test = 'test'
  }

  test (test) {
    this.test = test
  }
}

let t = new Test()
t.test('new Test')

Harap dicatat bahwa implementasi ini di NodeJS 6.10.

Sebagai solusinya (jika Anda tidak ingin menggunakan nama metode 'setTest' yang membosankan), Anda dapat menggunakan awalan untuk properti 'pribadi' Anda (seperti _test).

Buka Alat Pengembang Anda di jsfiddle .


Ini adalah kasus yang berbeda dari pertanyaannya.
CherryDT

0
  **Error Case:**

var handler = function(parameters) {
  console.log(parameters);
}

(function() {     //IIFE
 // some code
})();

Output: TypeError: (nilai menengah) (nilai antara) bukan sebuah fungsi * Cara Memperbaiki IT -> karena Anda kehilangan semi colan (;) untuk memisahkan ekspresi;

 **Fixed**


var handler = function(parameters) {
  console.log(parameters);
}; // <--- Add this semicolon(if you miss that semi colan .. 
   //error will occurs )

(function() {     //IIFE
 // some code
})();

kenapa error ini datang ?? Alasan: aturan khusus untuk penyisipan titik koma otomatis yang diberi standar ES6


0

Ketika saya membuat kelas root, yang metodenya saya definisikan menggunakan fungsi panah. Saat mewarisi dan menimpa fungsi asli, saya melihat masalah yang sama.

class C {
  x = () => 1; 
 };
 
class CC extends C {
  x = (foo) =>  super.x() + foo;
};

let add = new CC;
console.log(add.x(4));

ini diselesaikan dengan mendefinisikan metode kelas induk tanpa fungsi panah

class C {
  x() { 
    return 1; 
  }; 
 };
 
class CC extends C {
  x = foo =>  super.x() + foo;
};

let add = new CC;
console.log(add.x(4));
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.