Closure Compilerを使う!

エラーと警告のリファレンス

最終更新:

aias-closurecompiler

- view
管理者のみ編集可

トップページ >

エラーと警告のリファレンス

このページはClosure Compilerがコンパイル時に出力するエラーと警告のリファレンスです。

ここで対象となっているのはコードの内容が原因となって発生するエラーと警告だけです。例えば必須パラメータの指定漏れのような、リクエストそのものの不備が原因となって発生するエラーについてはこちらで詳しく解説しています。

  • このページは公式サイトのこちらを元に作成しました。

目次:

エラー

JSC_BITWISE_OPERAND_OUT_OF_RANGE

Operand out of range, bitwise operation will lose information: NUMBER {value of left-hand operand of bitwise operation} :

このエラーはビット演算において左側のオペランドのビット長が32ビットを超えていることを意味しています。例えば以下のコードでは 1024 * 1024 * 1024 * 2 が二進数表現で32ビットを超えているため、このエラーが発生します:

// Produces JSC_BITWISE_OPERAND_OUT_OF_RANGE error:
var y = 1024 * 1024 * 1024 * 2 >> 2;

JavaScript自身は左側のオペランドが32ビットより長いビット演算を許しているように見えますが、実はその場合オペランドはこっそり32ビットに丸められて処理されています。Compilerは間違ったデータの消失を防ぐためにこのエラーを出力します。

JSC_CONSTANT_REASSIGNED_VALUE_ERROR

constant {name of constant} assigned a value more than once.

このエラーは定数に対し値が複数回代入されていることを意味しています。Compilerは大文字とアンダースコアだけで構成されている2文字以上の変数を定数として扱います。定数は一旦初期化された後でその値が変更されることがあってはなりません。例えば以下のコードはエラーになります:

// Produces JSC_CONSTANT_REASSIGNED_VALUE_ERROR error:
var MY_CONSTANT = 1;
MY_CONSTANT = 2;

プロパティも同様です。以下のコードにも同じエラーが発生します:

// Produces JSC_CONSTANT_REASSIGNED_VALUE_ERROR error:
var myObject = {};
myObject.MY_CONSTANT = 1;
myObject.MY_CONSTANT = 2;

このエラーを修正する場合、その変数を定数とすべきかどうかをまず判断してください。

もしあなたがその値を定数として使っていてこのエラーが発生したのなら、Compilerは定数が意図せずに2度初期化されている箇所を見つける手助けをしてくれたことになます。全て大文字の変数を定数と見なすルールは、変更したくない値であることを明示するとても手軽な方法といえます。

  • 変数をCompilerに定数として認識させる手段としては、注釈コメントで@constタグを指定する方法もあります。

もしあなたがその値を定数として使っていなかったのであれば、変数名を少なくとも1つの小文字を含むものに変更してください。

JSC_DIVIDE_BY_0_ERROR

Divide by 0

このエラーは除算において値を0で割ろうとしている箇所があることを意味しています。0による除算が行われるとJavaScriptの実行時エラーが発生します。

JSC_DUPLICATE_EXTERN_INPUT

Duplicate extern input: {URL}

このエラーは同じexternファイルが複数回Compilerに渡されていることを意味しています。例えば同じURLを値にもつexterns_urlパラメータが2つ存在しているような場合に発生します。

このエラーを修正するには、重複した externs_url パラメータの一方を削除してください。

JSC_DUPLICATE_INPUT

Duplicate input: {File location}

このエラーは同じJavaScriptソースが複数回Compilerに渡されていることを意味しています。例えば同じURLを値にもつcode_urlパラメータが2つ存在しているような場合に発生します。

このエラーを修正するには、重複した code_url パラメータの一方を削除してください。

JSC_FRACTIONAL_BITWISE_OPERAND

Fractional bitwise operand: NUMBER {non-integer value}

このエラーはビット演算の値として整数ではなく浮動小数点数が使われていることを意味しています。例えば次のコードはこのエラーを発生させます:

// Produces JSC_FRACTIONAL_BITWISE_OPERAND error:
var x = 5 >> 2.5;
alert(x);

JSC_INDEX_OUT_OF_BOUNDS_ERROR

Array index out of bounds: {value of bad index}.

このエラーはコードが存在しない位置の配列要素にアクセスしようとしていることを意味しています。例えば下の例では最大のインデックスが 2 である配列に対し x[3] とアクセスしているため、このエラーが発生します:

// Produces JSC_INDEX_OUT_OF_BOUNDS_ERROR error:
var x = [0, 1, 2];
alert(x[3]);

配列インデックスが負数の場合にも、このエラーは発生します:

// Produces JSC_INDEX_OUT_OF_BOUNDS_ERROR error:
var x = [0, 1, 2];
alert(x[-1]);

// Produces JSC_INDEX_OUT_OF_BOUNDS_ERROR error:
var BAD_CONSTANT = -1;
var x = [1,2,3];
alert(x[BAD_CONSTANT]);

JSC_INVALID_GETELEM_INDEX_ERROR

Array index not integer: {non-integer value}.

このエラーは配列インデックスに文字列、浮動小数点数、もしくはそれ以外の整数以外の値が使用されていることを意味しています。例えば次のコードはこのエラーを発生させます:

// Produces JSC_INVALID_GETELEM_INDEX_ERROR:
var x = [1,2,3];
alert(x['a']);

JSC_NEGATING_A_NON_NUMBER_ERROR

Can't negate non-numeric value: {non-numeric value}

このエラーは負号(マイナス記号)が数値以外の式の前で使用されていることを意味しています。例えば次のコードはこのエラーを発生させます:

// Produces JSC_NEGATING_A_NON_NUMBER_ERROR:
var x = -'hello';

// Produces JSC_NEGATING_A_NON_NUMBER_ERROR:
var x = -{foo: 'bar'};

JSC_PARSE_ERROR

Parse error. {Description of syntax error}

このエラーはコンパイルしようとしているJavaScriptが文法的に正しくないことを意味しています。エラーメッセージに示された行を見てタイポやシンタックスエラーを確認し、コードをパース可能な状態に保ってください。

JSC_SHIFT_AMOUNT_OUT_OF_BOUNDS

Shift amount out of bounds: NUMBER {shift amount}.

このエラーはビットシフト演算子( << >> >>> )の2番目のオペランドが0未満または31より大きいことを意味しています。この2番目のオペランドはシフトの量を表すので、その値は必ず0と31の間でなければなりません。例えば次のコードはこのエラーを発生させます:

// Produces JSC_SHIFT_AMOUNT_OUT_OF_BOUNDS:
var x = 5 >> 32;
alert(x);

JSC_TRAILING_COMMA

Parse error. Trailing comma is not legal in an ECMA-262 object initializer.

このエラーは配列の最後の要素の後ろにカンマが付いていることを意味しています。例を示します:

// Produces JSC_TRAILING_COMMA error:
var x = [1,2,3,];

オブジェクトリテラル内のプロパティリストの末尾にカンマが付いていた場合も、同じエラーが発生します:

// Produces JSC_TRAILING_COMMA error:
var x = {
  foo: 'foo',
  bar: 'bar',
};

実際のところ上に示したコードは多くのブラウザで問題なく動作するのですが、これらは正しいECMAScriptとはいえません。末尾のカンマを削除しエラーを修正してください。

var x = [1,2,3];

var x = {
  foo: 'foo',
  bar: 'bar'
};

警告

JSC_BAD_DELETE_OPERAND

delete operator needs a reference operand

この警告は delete 演算子がオブジェクトプロパティ、変数、配列要素以外の何らかの値に対し適用されていること意味しています。例えば文字列リテラルや数値に delete 演算子を適用するとこの警告が発生します:

delete 1;
delete 'abc';

JSC_BAD_TYPE_FOR_BIT_OPERATION

{Name of bad operand} :

この警告はビット演算子のオペランドに整数以外の値が含まれていることを意味しています。以下のコードの最後の2行はこの警告を発生させます:

var obj = {};
var x = 5 >> obj; // obj is not an integer
var x = obj >> 5; // obj is still not an integer

JavaScriptに定義されているビット演算子は以下のとおりです:

  • & : ビット単位のAND
  • | : ビット単位のOR
  • ^ : ビット単位のXOR
  • ~ : ビット単位のNOR
  • << : 左シフト
  • >> : 右シフト(左端に符号ビットをコピー)
  • >>> : 右シフト(左端ビットを0埋め)

JSC_CONSTRUCTOR_NOT_CALLABLE

Constructor function (this:{Name of constructor}): ? should be called with the "new" keyword.

この警告はコンストラクタが new キーワードを使わずに通常の関数のように呼び出されている箇所があることを意味しています。CompilerはJSDocアノテーションの@constructorタグが付与されている関数だけをコンストラクタとして扱います。次のコードはこの警告を発生させます:

// Produces JSC_CONSTRUCTOR_NOT_CALLABLE warning:
/**
 * @constructor
 */

function MyClass() {
  this.foo = 'bar';
}
var y = MyClass();

対照的に、以下のコードでは警告は発生しません:

function MyClass() {
  this.foo = 'bar';
}
var y = MyClass();

この警告が発生した場合、該当する行で new キーワードが抜けているところがないか確認してください。

JSC_FUNCTION_MASKS_VARIABLE

function {name of function} masks variable.

この警告はコード内で関数と同じ名前の変数が存在していることを意味しています。例えば、次のコードはこの警告を発生させます:

// Produces JSC_FUNCTION_MASKS_VARIABLE warning:
var hello = 1;
function hello() {
  alert('hi');
}

このような名前の重複は単にコードを混乱させるだけでなく、Compilerが行ういくつかのコード変換処理が依拠している前提にも違反しています。この警告を除去するには、関数か変数のどちらかの名前を変更してください。

JSC_INVALID_FUNCTION_DECL

function declaration must have a name

この警告は関数宣言において function キーワードと引数リストの間に関数名が定義されていないことを意味しています。以下はその例です:

// Produces JSC_INVALID_FUNCTION_DECL warning:
function (x) {
  return x + 1;
}

Compilerは上のコードを記述ミスと判断します。

このような関数宣言と「無名関数」の宣言は同じではないという点に注意してください。無名関数は変数に代入されるか、関数に引数として渡されるかたちで宣言されます。以下の例では警告は発生しません:

var y = function (x) {
  return x + 1;
}

あるいは:

doStuff(15, function(x) {return x + 1;});

JSC_NAMESPACE_REDEFINED

namespace {name of object} should not be redefined

この警告は、オブジェクトの重要なプロパティがそのオブジェクトの再初期化によって消去されたかもしれないことを意味しています。エラーメッセージの中の namespace (名前空間)という単語は、関数や変数をメンバとして保持するオブジェクトを指しています。例えば以下のコードにおいて、コンストラクタ関数 b は名前空間オブジェクト a のプロパティとして保持されています:

// Produces JSC_NAMESPACE_REDEFINED warning:
var a = {};

/** @constructor */

a.b = function() {
  this.msg = 'hi';
};
a = {};
var x = new a.b();

5行目の文  a = {}  は既存の変数 a を、そこに含まれる b もろとも上書きしています。

この警告が発生した場合、メッセージに示されたオブジェクトが持つ全てのプロパティを本当に消去してよかったのか確認してください。

JSC_NOT_A_CONSTRUCTOR

cannot instantiate non-constructor

この警告はコンストラクタでない何かが new キーワードとともに使われたことを意味しています。例えば以下のコードは数値の 4 をインスタンス化しようとしているため、この警告が発生します:

// Produces JSC_NOT_A_CONSTRUCTOR warning:
var x = new 4;

CompilerはJSDocアノテーションの@constructorタグが付与されている関数はコンストラクタであると考えます。下はその例です:

/**
 * @constructor
 */

function MyClass() {
  this.foo = 'bar';
}
var obj = new MyClass();
alert(obj.foo);

同じコードでも @constructor タグが付いていなければ、この警告の対象となります:

// Produces JSC_NOT_A_CONSTRUCTOR warning:
function MyClass() {
  this.foo = 'bar';
}
var obj = new MyClass();
alert(obj.foo);

JSC_NOT_FUNCTION_TYPE

{expression type} expressions are not callable.

この警告は関数でないものが関数としてコールされていることを意味します。例えば、次のコードはこの警告を発生させます:

// Produces JSC_NOT_FUNCTION_TYPE warning:
var nonfunction = 4;
var resultOfCallingNonfunction = nonfunction();

JSC_REDECLARED_VARIABLE

Redeclared variable: {variable name} :

この警告は宣言済みの変数に対し再度 var キーワードが使われていることを意味しています。以下はその例です:

// Produces JSC_REDECLARED_VARIABLE warning:
var a = 'First declaration';
var a = 'Second declaration';

関数内でその関数のパラメータと同じ名前の変数を宣言した場合も、同じ警告が発生します:

function f(a) {
  var a = 2;
}

JavaScriptではif文やループのブロックが独立したスコープとならないことを忘れないでください。このため、次のコードもやはり警告を発生させます:

function x(y) {
  if (true) {
    var y;
  }
}

このような名前の重複は単にコードを混乱させるだけでなく、Compilerが行ういくつかのコード変換処理が依拠している前提にも違反しています。この警告を除去するには、変数のどちらかの名前を変更してください。

JSC_REFERENCE_BEFORE_DECLARE

Variable referenced before declaration: {name of variable}.

この警告は、ある変数が var キーワードによる宣言より前に使用されていることを意味しています。例えば、次のコードはこの警告を発生させます:

// Produces JSC_REFERENCE_BEFORE_DECLARE warning:
x = 1;
var x = 2;

JSC_SET_WITHOUT_READ

{Name of property}

この警告は、オブジェクトのプロパティに値が設定された後、誰もそのプロパティにアクセスしていないことを意味しています。例えば、次のコードはこの警告を発生させます:

// Produces JSC_SET_WITHOUT_READ warning:
var obj = {goodProp: 1};
obj.unusedProp = 3;
alert(obj.goodProp);

この警告が発生した場合、そのプロパティが本当に必要かどうかをチェックし、不要であれば削除してください。プロパティが間違いなくコード内で使用されているという確信があるのであれば、タイポが原因で別のプロパティがアクセスされている箇所がないか確認してください。

JSC_SUSPICIOUS_SEMICOLON

If this if/for/while really shouldn't have a body, use {}.

この警告は if for while の直後にセミコロンが置かれていることを意味しています。以下はその例です:

// Produces JSC_SUSPICIOUS_SEMICOLON warning:
if (true);
else alert('no');

Compilerは本来は if (true) とセミコロンの間に何らかのコードが書かれるはずだったと考え、このコードを記述ミスと見なします。

もしあなたが本当に if for while の後に何も処理を置きたくなかったのであれば、セミコロンの代わりに空の中括弧を使ってください:

if (true) {}
else alert('no');

JSC_TYPE_MISMATCH

{description of mismatch}
found : {type of mismatched expression}

この警告は式の中でそのコンテキストからは想定されていない値が使われていることを意味しています。例えば以下のコードはオブジェクトリテラル{foo: bar}と数値を比較しているため、この警告が発生します:

// Produces JSC_TYPE_MISMATCH warning:
if ({foo: bar} >= 42) {
  alert('yes');
}

同様に、以下のコードではオブジェクトリテラルがビット単位AND演算の対象になっているため、この警告が発生します:

// Produces JSC_TYPE_MISMATCH warning:
var obj = {};
var x = 5 & obj;

この警告の原因となっている箇所を見つけるには、エラーメッセージに示された行の中でメッセージの found : の部分に挙げられたタイプに一致する式を探してください。

JSC_UNDEFINED_NAME

Warning: "{Name of property} is never defined"

この警告は初期化されていないプロパティがアクセスされていることを意味しています。以下はその例です:

// Produces JSC_UNDEFINED_NAME warning:
var root = {};
var reference = root.child;

この警告を修正するには、参照される前にプロパティに値をセットしてください:

var root = {};
root.child = 1;
var reference = root.child;

JSC_UNDEFINED_VARIABLE

variable {name of variable} is undefined

この警告は変数が var キーワードによって宣言されていないことを意味しています。例えば以下のコードが変数 firstUseOfName が出現する最初のものであれば、この警告が発生します:

// Produces JSC_UNDEFINED_VARIABLE warning:
firstUseOfName = 1;

この警告を修正するには、変数の前に var を入れてください:

var firstUseOfName = 1;

JSC_UNSAFE_NAMESPACE

incomplete alias created for namespace {name of object}.

この警告は、あなたのコードがADVANCED_OPTIMIZATIONSレベルのコンパイル後には利用できなくなるオブジェクトプロパティに依存していることを意味しています。エラーメッセージの中の namespace (名前空間)という単語は、関数や変数をメンバとして保持するオブジェクトを指しています。例えば以下のコードで、関数 c は名前空間 a.b のプロパティとして保持されています:

// Produces JSC_UNSAFE_NAMESPACE warning:
var a = {};
a.b = {};

/** @constructor */

a.b.c = function(){
  this.msg = 'hi';
};
var d = a.b;

最後の行は安全でない a.b への参照を含んでいます。この行では変数 d a.b を代入していますが、 ADVANCED_OPTIMIZATIONS a.b.c という階層構造を単純な変数に置き換えた後、 a.b をコードから取り除きます。このため、 a.b への参照は安全でないものとしてCompilerは警告を出力します。

  • ADVANCED_OPTIMIZATIONS レベルがコードに求める制約について、詳しくはこちらを参照してください。

JSC_UNSAFE_THIS

dangerous use of this in static method {name of method}.

この警告は this がオブジェクトの(プロトタイプメソッドではなく)スタティックなメソッドの中で使用されていることを意味しています。その結果として、ADVANCED_OPTIMIZATIONSでコンパイルを行うと this はそれが定義されているメソッドを参照しなくなってしまうと思われます。例えば下のコードのメソッド obj.myMethod() は危険な this を含んでいます:

// Produces JSC_UNSAFE_THIS warning:
var obj = {};
obj.myMethod = function() {
  this.myProperty = 1;
};
obj.myMethod();
alert(obj.myProperty); // We want this to say '1'

このソースコードの中で、 obj.myMethod() の中の this obj を参照しています。しかし ADVANCED_OPTIMIZATIONS レベルのコンパイラはより強力な圧縮のための準備段階として、 obj.myMethod obj$myMethod という単純なシンボルに平坦化します。この変換によって関数はオブジェクトのプロパティではなく、ただのグローバルな関数になります。このコンテキストの中では、 this はグローバルな this (もしコードが標準的なWebページに置かれているなら、 window オブジェクト)を参照しています。

しかしコンストラクタ関数の中では、プロパティの平坦化が同様の問題を引き起こすことはありません。コンストラクタが new キーワードと共に呼び出されるとき、内部の this が指すものは平坦化によって変化しないからです。例えば次のコードでは警告は発生しません:

var obj = {};

/**
 * @constructor
 */

obj.myMethod = function() {
  this.myProperty = 1;
};
var instance = new obj.myMethod();
alert(instance.myProperty); // We want this to say '1'

このバージョンのコードでは、 myMethod はコンストラクタとして( new キーワードと共に)呼び出されています。このコンストラクタの中で this obj ではなく new obj.myMethod(); が生成するオブジェクトを参照しています。従って obj.myMethod() でも obj$myMethod() でも this の意味は同じなのです。

ただしここで、Compilerが obj.myMethod() をコンストラクタとして認識しているのは、それが@constructorタグでアノテートされているからである点に注意してください。もし上のコードから @constructor タグと除去すると、最初の例と同様に警告が発生します。コンストラクタ関数の実行時にこの警告が発生するのを防ぐため、全てのコンストラクタに @constructor アノテーションを付加するようにしてください。

  • この問題についてはこちらの説明も参照してください。

JSC_USED_GLOBAL_THIS

dangerous use of the global this object.

この警告は this がプロトタイプメソッドまたはコンストラクタ関数の外で使用されていることを意味しています。例えば以下のコードはこの警告を発生させます:

// Produces JSC_USED_GLOBAL_THIS warning:
this.foo = 1;

このケースで this は実際にグローバルオブジェクトを参照しています。標準的なWebページでは、グローバルオブジェクトは window オブジェクトと同一です。もしこの警告を受け取った場合、グローバルオブジェクトへの参照が本当に意図的なものであるか確認してください。

Compilerは下の例のように@constructorアノテーションが付加されている場合だけ、ある関数がコンストラクタであることを認識します:

/**
 * @constructor
 */

function MyFunction() {
  this.foo = 1;
}

JSC_USELESS_CODE

Suspicious code. This code lacks side-effects. Is there a bug?

この警告はコードに何の効力も持たないステートメントが含まれていることを意味しています。1文字のミスタイプによって無意味なJavaScriptステートメントがうっかり作られてしまうケースはいくつか考えられます。例えば、下のコードの3行目は単独の文字列リテラルからなっていて、文法的には正しいJavaScriptですが、何の役割も果たしません:

// Produces JSC_USELESS_CODE warning:
var s = "this string is "
  "continued on the next line but you forgot the +";

このコードの作者は2行目の最後に + を入れて、2行を1つのステートメントに収めようとしていたのでしょう。JavaScriptは行末のセミコロンを省略できるので、 + の抜けはコードを2つのステートメントに分けることになりました。そして後ろの方は効力を失ってしまったのです。

意味のないコードがうっかり作られてしまう簡単な例をもうひとつ示します。下のコードの作者は変数 x 1 を代入しようとしたのですが、 = を1つ余計に含めてしまいました:

// Produces JSC_USELESS_CODE warning:
x == 1;

x 1 が代入される代わりに、このステートメントは効力のない真偽式になっています。

この警告を受け取った場合、ステートメントを無意味化してしまうようなタイポがないか探してみてください。

JSC_VAR_ARGS_MUST_BE_LAST

variable length argument must be last.

この警告は、 var_args という名前の関数パラメータが使用されているにもかかわらず、その後ろに別のパラメータが定義されていることを意味しています。 var_args は特殊なパラメータで、その関数が可変数のパラメータを取ることをCompilerに示すために使われます。そして関数が var_args パラメータを持つ場合、それは必ず最後尾のパラメータでなければなりません。

例えば以下のコードはこの警告を発生させます:

// Produces JSC_VAR_ARGS_MUST_BE_LAST warning:
function hi(a, var_args, b) {
  alert(a);
}

JSC_WRONG_ARGUMENT_COUNT

Function {function name}: called with {number of arguments in call} argument(s). Function requires at least {number of required arguments in function definition} argument(s) [and no more than {number of arguments in function definition} argument(s)].

この警告は関数呼び出しの際に引数の数が間違っていることを意味しています。例えば以下のコードはこの警告を発生させます。関数 hi() は2つの引数を取ると定義されているにもかかわらず、最後の行で行われている呼び出しでは引数が1つしか渡されていないからです:

// Produces JSC_WRONG_ARGUMENT_COUNT warning:
function hi(a, b){
  alert(a + b);
}
hi('hello');

JavaScriptは関数呼び出しにおいて引数の数が変化することを許しているので、この警告はコンパイルを妨げません。しかしコード内の間違いを見つける助けにはなってくれるはずです。

もしあなたが引数の数が変動する関数を使っており、かつこの警告を間違いの検出に用いたいと考えているなら、 var_args が役に立ちます。 var_args は引数の数が可変であることをCompilerに明示するための特殊なパラメータです。Compilerは関数の最後尾のパラメータとして var_args を見つけると、その関数の引数の数が可変であることを認識します。例えば以下のコードでは警告は発生しません

function hi(a, var_args){
  var msg = a;
  if (arguments.length >= 3) {
    msg += arguments[2];
  }
  alert(msg);
}
hi('hello');
hi('hello', 'goodbye', 'what?');

上の例の中で、JavaScriptの組み込み変数である arguments を使って付け加えられた引数にアクセスしている点に注意してください。 var_args はCompilerにとっては特別な意味をもっていますが、実体としては関数呼び出しの際に渡される2番目の引数にすぎません。追加された引数にアクセスするには arguments を使ってください。 arguments は配列のように動作するオブジェクトで、関数に渡された全てのパラメータを要素に含んでいます。

関数が var_args パラメータを持っていても、関数に渡されたパラメータの数が var_args より前に定義されているパラメータの数より少ない場合には、やはりComplilerはこの警告を発生させます。以下はその例です:

// Produces JSC_WRONG_ARGUMENT_COUNT:
function hi(a, b, var_args){
  alert(a + b);
}
hi('hello');

この関数は少なくとも2つの引数を必要とします。


目安箱バナー