捕捉されなかった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

このエラーは、3行目にセミコロンがないために発生します。

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 2018年

1
これは正気ではなく、私はこの投稿にとても感謝しています。この「...は関数ではありません」というエラーが表示され続けるifと、React useEffect()関数のステートメントの後に状態を設定していました。
Rahul Nath

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.

上記のケースは、たまたまreturn / continue / break / ++ /-になります。リンターはデッドコードまたは++ /-構文エラーでこれをキャッチします(++ /-が現実的に発生することは決してありません)。

最後に、ファイルの連結を機能させたい場合は、各ファイルがセミコロンで終わっていることを確認してください。バンドラープログラムを使用している場合(推奨)、自動的にこれを実行する必要があります。


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-loopに置き換えたところ、すぐに文句を言わなくなりました。私はそれが不平を言っている線を示さないのは本当に嫌いですが、とにかく、私を二度私に恥をかかせてください。


私の推測では、あなたの問題はとは何かだったということです。この
Brandito

これは、質問の内容とは異なるケースです。
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));
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.