Uncaught TypeError: (проміжне значення) (…) - це не функція


128

Все працює добре, коли я записав js логіку в закритому вигляді як єдиний js-файл, як:

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

але коли я намагаюся вставити альтернативну функцію журналу перед цим закриттям у той самий файл 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)

він скаржиться, що існує TypeError:

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

Що я зробив не так?

Відповіді:


275

Помилка є результатом відсутньої крапки з комою в третьому рядку:

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

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

Специфікація ECMAScript має специфічні правила автоматичної вставки крапки з комою , однак у цьому випадку крапка з комою не вставляється автоматично, оскільки вираз у дужках, що починається у наступному рядку, може бути інтерпретований як список аргументів для виклику функції.

Це означає, що без цього крапки з комою, анонімна window.Glogфункція викликала функцію в якості msgпараметра, після (window)чого згодом намагалася викликати те, що було повернуто.

Ось як трактували код:

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

4
@armnotstrong Josh був швидшим, і відповідь така ж :)
mrlew

1
Дякую вам сер! Мій підводник автоматично видалив крапку з комою, і все зламалося :)
Jonas Lomholdt,

1
приголомшливий !!! Дуже дякую!! Я майже втратив усе волосся на цьому ...
TMS

1
Це, мій друже, золото!
LihO

1
це божевільно, і я так вдячний за цю посаду. Я встановлював стан після ifзаяви у useEffect()функції React, коли я постійно отримував цю помилку "... не функція".
Рахул Нат

7

Зробити правила крапки з комою просто

Кожен рядок , яка починається з (, [`, або будь-який оператор (/, +, - єдиним дійсними ті), повинен починатися крапкою з комою.

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

Це запобігає а

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

жахливість.

Додаткова примітка

Зазначимо, що буде: дужки будуть індексувати, круглі дужки розглядаються як параметри функції. Зворотний вибір перетвориться в тег з шаблоном , і регулярні вирази або явно підписані цілі числа перетворяться в оператори. Звичайно, ви можете просто додати крапку з комою до кінця кожного рядка. Добре пам’ятати, хоча, коли ви швидко розробляєте прототип і скидаєте крапки з комою.

Крім того, додавання крапки з комою до кінця кожного рядка не допоможе вам у наступному, тому пам’ятайте про такі твердження, як

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.

Вищенаведений випадок стане поверненням / продовженням / перервою / ++ / -. Будь-який лінійник сприймає це за допомогою мертвого коду або ++ / - синтаксичної помилки (++ / - ніколи не відбудеться реально).

Нарешті, якщо ви хочете, щоб з'єднання файлів працювало, переконайтеся, що кожен файл закінчується крапкою з комою. Якщо ви використовуєте програму-постачальник (рекомендується), вона повинна робити це автоматично.


5

Випадок помилки:

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

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

Вихід:

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

Виправлення: Вам не вистачає крапки з комою (;) для розділення виразів

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

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

3

Для мене це було набагато простіше, але мені знадобилося трохи часу, щоб зрозуміти це. В основному у нас був .jslib

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

Виходить Unity (emscripten?) Просто не любить цей синтаксис. Ми замінили його на добрий старий для циклу, і він перестав скаржитися відразу. Я дуже ненавиджу, що на ній не видно лінії, на яку вона скаржиться, але все одно, обдуриш мене двічі соромно.


я гадаю, що ваше питання було пов'язане з цим
Брандіто,

Це інший випадок, ніж те, про що йдеться.
CherryDT

@CherryDT це не так, оскільки помилка, яку я отримував, була саме такою.
tfrascaroli

Ні, це питання стосується помилок, які ви отримуєте від випадкового виклику щось як функції через відсутність крапки з комою між оператором та a (в наступному рядку. Я нічого не бачу у вашому випадку. Питання складається не лише з назви!
CherryDT

1

Я зіткнувся з цією проблемою, коли створив новий клас ES2015, де ім'я властивості було рівним імені методу.

наприклад:

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

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

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

Зверніть увагу, що ця реалізація була в NodeJS 6.10.

Як вирішення (якщо ви не хочете використовувати нудне ім'я методу "setTest"), ви можете використовувати префікс для своїх "приватних" властивостей (наприклад _test).

Відкрийте Інструменти для розробників у jsfiddle .


Це інший випадок, ніж те, про що йдеться.
CherryDT

0
  **Error Case:**

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

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

Вихід: TypeError: (проміжне значення) (проміжне значення) не є функцією * Як виправити ІТ -> тому що вам не вистачає напівколан (;) для розділення виразів;

 **Fixed**


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

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

чому ця помилка виникає ?? Причина: конкретні правила автоматичної вставки крапки з комою, яким надано стаціонари ES6


0

Коли я створюю кореневий клас, методи якого я визначив за допомогою функцій стрілок. Під час успадкування та перезапису вихідної функції я помітив ту саму проблему.

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

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

це вирішується шляхом визначення методу батьківського класу без функцій зі стрілками

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

let add = new CC;
console.log(add.x(4));
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.