Yakalanmamış TypeError: (ara değer) (…) bir işlev değil


129

Js mantığını bir kapanışta tek bir js dosyası olarak yazdığımda her şey yolunda gidiyor:

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

ancak aynı js dosyasına bu kapanıştan önce bir günlük kaydı alternatif işlevi eklemeye çalıştığımda,

 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)

bir TypeError olduğundan şikayet eder:

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

Neyi yanlış yaptım?

Yanıtlar:


276

Hata, üçüncü satırdaki eksik noktalı virgülün bir sonucudur:

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

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

ECMAScript belirtiminin otomatik noktalı virgül ekleme için belirli kuralları vardır , ancak bu durumda bir noktalı virgül otomatik olarak eklenmez, çünkü sonraki satırda başlayan parantezli ifade bir işlev çağrısı için bir bağımsız değişken listesi olarak yorumlanabilir.

Bu, bu noktalı virgül olmadan, anonim window.Glogişlevin msgparametre olarak bir işlevle çağrıldığı ve ardından (window)döndürülen her şeyi çağırmaya çalıştığı anlamına gelir.

Kod şu şekilde yorumlanıyordu:

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

4
@armnotstrong Josh daha hızlıydı ve cevap aynı :)
mrlew

1
Teşekkürler bayım!
Linterim

1
müthiş !!! Çok teşekkür ederim!! Bunda neredeyse tüm saçlarımı kaybettim ...
TMS

1
Bu, arkadaşım, altın!
LihO

1
bu çılgınlık ve bu yazı için çok minnettarım. Bu "... bir işlev değil" hatasını almaya devam ettiğimde if, bir React useEffect()işlevindeki bir ifadeden sonra durumu ayarlıyordum .
Rahul Nath

7

Noktalı virgül kurallarını basitleştirmek için

Bir ile başlar her çizgi (, [`veya herhangi operatör (/, +, - tek geçerli olanlar), bir noktalı virgül ile başlamalıdır.

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

Bu bir

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

Monstrocity.

Ek not

Ne olacağını belirtmek gerekirse: parantezler indekslenecek, parantezler fonksiyon parametreleri olarak değerlendirilecektir. Ters işaret etiketli bir şablona dönüşür ve normal ifade veya açıkça işaretlenmiş tamsayılar işleçlere dönüşür. Tabii ki, her satırın sonuna bir noktalı virgül ekleyebilirsiniz. Hızlı bir şekilde prototip oluştururken ve noktalı virgül bırakırken akılda kalmak iyidir.

Ayrıca, her satırın sonuna noktalı virgül eklemek aşağıdakiler konusunda size yardımcı olmaz, bu nedenle

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.

Yukarıdaki durum, return / continue / break / ++ / - olacaktır. Herhangi bir linter bunu ölü kod veya ++ / - sözdizimi hatasıyla yakalayacaktır (++ / - asla gerçekçi olmayacak).

Son olarak, dosya birleştirmenin çalışmasını istiyorsanız, her dosyanın noktalı virgülle bittiğinden emin olun. Bir paketleyici programı kullanıyorsanız (önerilen), bunu otomatik olarak yapmalıdır.


5

Hata Durumu:

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

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

Çıktı:

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

Düzeltme: İfadeleri ayırmak için noktalı virgül (;) eksik

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

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

3

Benim için çok daha basitti ama anlamam biraz zaman aldı. Temelde .jslib'imizde vardı

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

Unity'nin (emscripten?) Bu sözdizimini sevmediği ortaya çıktı. Onu eski güzel bir döngü ile değiştirdik ve hemen şikayet etmeyi bıraktı. Şikayet ettiği çizgiyi göstermemesinden gerçekten nefret ediyorum, ama yine de, beni iki kez utandırın.


benim tahminim Sorununuz ile ilgili bir şey olmasıdır bu
Brandito

Bu, sorunun ne hakkında olduğundan farklı bir durum.
CherryDT

@CherryDT değil, çünkü aldığım hata aynıydı.
tfrascaroli

Hayır, bu soru, ifade ile (sonraki satırda arasında noktalı virgül bulunmaması nedeniyle yanlışlıkla bir şeyi işlev olarak çağırmaktan aldığınız hatalarla ilgilidir . Senin durumunda bunların hiçbirini görmüyorum. Soru sadece başlığından ibaret değil!
CherryDT

1

Özellik adının yöntem adına eşit olduğu yeni bir ES2015 sınıfı oluşturduğumda bu sorunla karşılaştım.

Örneğin:

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

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

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

Lütfen bu uygulamanın NodeJS 6.10'da yapıldığını unutmayın.

Bir çözüm olarak (sıkıcı 'setTest' yöntem adını kullanmak istemiyorsanız), 'özel' özellikleriniz için bir önek kullanabilirsiniz (gibi _test).

Geliştirici Araçlarınızı jsfiddle'da açın .


Bu, sorunun ne hakkında olduğundan farklı bir durum.
CherryDT

0
  **Error Case:**

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

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

Çıktı: TypeError: (ara değer) (ara değer) bir işlev değil * BT Nasıl Onarılır -> çünkü ifadeleri ayırmak için yarı colan (;) eksiksiniz;

 **Fixed**


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

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

bu hata neden geliyor? Sebep: ES6 standartları verilen otomatik noktalı virgül ekleme için belirli kurallar


0

Yöntemlerini ok işlevlerini kullanarak tanımladığım bir kök sınıf oluşturduğumda. Orijinal işlevi devralırken ve üzerine yazarken aynı sorunu fark ettim.

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

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

bu, ana sınıfın yöntemini ok fonksiyonları olmadan tanımlayarak çözülür.

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

let add = new CC;
console.log(add.x(4));
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.