Uncaught TypeError: (промежуточное значение) (…) не является функцией


130

Все работает нормально, когда я написал логику 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

Что я сделал не так?

Ответы:


277

Ошибка возникает из-за отсутствия точки с запятой в третьей строке:

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 Джош был быстрее, и ответ тот же :)
mrlew

1
Спасибо, сэр! Мой
линтер

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

monstrocity.

Дополнительное примечание

Чтобы упомянуть, что произойдет: скобки будут индексировать, круглые скобки будут рассматриваться как параметры функции. Обратный апостроф преобразуется в шаблон с тегами , а регулярное выражение или целые числа с явным знаком - в операторы. Конечно, вы можете просто добавить точку с запятой в конце каждой строки. Это хорошо, когда вы быстро создаете прототип и опускаете точки с запятой.

Кроме того, добавление точки с запятой в конец каждой строки не поможет вам в следующих случаях, поэтому имейте в виду такие утверждения, как

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?) Просто не нравится этот синтаксис. Мы заменили его на старый добрый цикл for, и он сразу перестал жаловаться. Я действительно ненавижу то, что в нем нет той строки, на которую он жалуется, но в любом случае, обмануть меня дважды, позор мне.


я предполагаю, что ваша проблема как-то связана с этим
Брандито

Это совсем не тот случай, о котором идет речь.
CherryDT

@CherryDT, это не так, поскольку ошибка, которую я получал, была точно такой же.
тфраскароли

Нет, это вопрос об ошибках, которые возникают при случайном вызове чего-либо как функции из-за отсутствия точки с запятой между оператором и 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.