Uncaught TypeError: (wartość pośrednia) (…) nie jest funkcją

130

Wszystko działa dobrze, gdy napisałem logikę js w zamknięciu jako pojedynczy plik js, jako:

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

ale kiedy próbuję wstawić alternatywną funkcję logowania przed tym zamknięciem w tym samym pliku js,

 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)

narzeka, że ​​jest TypeError:

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

Co zrobiłem źle?

armnotstrong
źródło

Odpowiedzi:

277

Błąd wynika z braku średnika w trzecim wierszu:

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

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

Specyfikacja ECMAScript ma określone zasady automatycznego wstawiania średników , jednak w tym przypadku średnik nie jest wstawiany automatycznie, ponieważ wyrażenie w nawiasach rozpoczynające się w następnym wierszu może być interpretowane jako lista argumentów dla wywołania funkcji.

Oznacza to, że bez tego średnika window.Glogwywoływano funkcję anonimową z funkcją jako msgparametrem, po (window)czym następowała próba wywołania tego, co zostało zwrócone.

Oto jak był interpretowany kod:

window.Glog = function(msg) {
  console.log(msg);
}(function(win) {
  // ...
})(window);
Josh Crozier
źródło
4
@armnotstrong Josh był szybszy, a odpowiedź jest taka sama :)
mrlew
1
Dziękuję Panu! Mój linter automatycznie usunął średnik i wszystko się zepsuło :)
Jonas Lomholdt
1
niesamowite!!! Dziękuję bardzo!! Prawie straciłam wszystkie włosy na tym ...
TMS
1
To, mój przyjacielu, jest złoto!
LihO
1
to jest szalone i jestem bardzo wdzięczny za ten post. Ustawiałem stan po ifinstrukcji w useEffect()funkcji React, gdy otrzymywałem ten błąd „... nie jest funkcją”.
Rahul Nath
7

Aby uprościć reguły dotyczące średników

Każda linia, która zaczyna się od (, [`lub każdy podmiot (/, +, - ważne są tylko te), musi zaczynać się średnikiem.

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

Zapobiega to

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

potworność.

Dodatkowa uwaga

Aby wspomnieć, co się stanie: nawiasy będą indeksowane, nawiasy będą traktowane jako parametry funkcji. Lewy przycisk zmieniłby się w otagowany szablon , a wyrażenie regularne lub jawnie podpisane liczby całkowite zamieni się w operatory. Oczywiście możesz po prostu dodać średnik na końcu każdego wiersza. Warto jednak o tym pamiętać, gdy szybko tworzysz prototypy i upuszczasz średniki.

Ponadto dodanie średników na końcu każdej linii nie pomoże Ci w następujących kwestiach, więc pamiętaj o stwierdzeniach takich jak

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.

Powyższy przypadek spowoduje powrót / kontynuowanie / przerwanie / ++ / -. Każdy linter złapie to martwym kodem lub błędem składni ++ / - (++ / - nigdy się nie wydarzy).

Wreszcie, jeśli chcesz, aby konkatenacja plików działała, upewnij się, że każdy plik kończy się średnikiem. Jeśli używasz programu typu bundler (zalecane), powinien to zrobić automatycznie.

Nicholas Pipitone
źródło
5

Przypadek błędu:

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

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

Wynik:

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

Poprawka: brakuje średnika (;) do oddzielenia wyrażeń

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

( cameraInfo.findtext != "" ) ? searchQuery : userListQuery;
Shashwat Gupta
źródło
3

Dla mnie było to znacznie prostsze, ale zajęło mi trochę czasu, zanim to rozgryzłem. Zasadniczo mieliśmy w naszym .jslib

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

Okazuje się, że Unity (emscripten?) Po prostu nie lubi tej składni. Zastąpiliśmy go starą, dobrą pętlą for i od razu przestał narzekać. Naprawdę nienawidzę tego, że nie pokazuje linii, na którą narzeka, ale tak czy inaczej, oszukuj mnie dwa razy, wstydź mnie.

tfrascaroli
źródło
Domyślam się, że twój problem był związany z tym
Brandito
To jest inny przypadek niż to, o co chodzi.
CherryDT
@CherryDT tak nie jest, ponieważ błąd jaki otrzymywałem był dokładnie ten sam.
tfrascaroli
Nie, to pytanie dotyczy błędów, które pojawiają się w wyniku przypadkowego wywołania czegoś jako funkcji, ponieważ między instrukcją a a (w następnym wierszu nie ma średnika . Nie widzę tego w twoim przypadku. Pytanie składa się nie tylko z tytułu!
CherryDT
1

Miałem do czynienia z tym problemem, kiedy tworzyłem nową klasę ES2015, w której nazwa właściwości była równa nazwie metody.

na przykład:

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

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

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

Zwróć uwagę, że ta implementacja była w NodeJS 6.10.

Aby obejść ten problem (jeśli nie chcesz używać nudnej nazwy metody „setTest”), możesz użyć przedrostka dla swoich właściwości „prywatnych” (np _test.).

Otwórz narzędzia programistyczne w jsfiddle .

GuyT
źródło
To jest inny przypadek niż to, o co chodzi.
CherryDT
0
  **Error Case:**

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

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

Wynik: TypeError: (wartość pośrednia) (wartość pośrednia) nie jest funkcją * Jak to naprawić -> ponieważ brakuje średnika (;) do oddzielenia wyrażeń;

 **Fixed**


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

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

dlaczego pojawia się ten błąd? Powód: szczególne zasady automatycznego wstawiania średników, które są zgodne ze standardami ES6

Shashwat Gupta
źródło
0

Kiedy tworzę klasę główną, której metody zdefiniowałem za pomocą funkcji strzałek. Podczas dziedziczenia i nadpisywania oryginalnej funkcji zauważyłem ten sam problem.

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

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

rozwiązuje się to poprzez zdefiniowanie metody klasy nadrzędnej bez funkcji strzałkowych

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

let add = new CC;
console.log(add.x(4));
Lourdes Vílchez
źródło