この章は、ECMAScript仕様で標準化されたグローバル変数のリファレンスです。ウェブブラウザにはさらに多くのグローバル変数があり、MDNにリストされています。すべてのグローバル変数は、グローバルオブジェクト(ブラウザではwindow、グローバルオブジェクトを参照)の(独自のまたは継承された)プロパティです。
以下のコンストラクタの詳細については、括弧内に示されているセクションを参照してください。
Array (Arrayコンストラクタ)Boolean (プリミティブのラッパーオブジェクト)Date (Dateコンストラクタ)Function (new Function()を使ったコードの実行)Number (プリミティブのラッパーオブジェクト)Object (任意の値をオブジェクトに変換する)RegExp (正規表現の作成)String (プリミティブのラッパーオブジェクト)これらのコンストラクタの詳細については、エラーコンストラクタを参照してください。
Error
EvalError
RangeError
ReferenceError
SyntaxError
TypeError
URIError
いくつかのグローバル関数はコンストラクタではありません。このセクションにリストされています。
以下の関数は、URIの様々なエンコードとデコード方法を処理します。
encodeURI(uri)
uri内の特殊文字をパーセントエンコードします。特殊文字は、以下の文字を除くすべてのUnicode文字です。
URI文字 |
|
エンコードされない |
|
例えば
> encodeURI('http://example.com/Für Elise/')
'http://example.com/F%C3%BCr%20Elise/'encodeURIComponent(uriComponent)
uriComponent内のすべての文字をパーセントエンコードします。ただし、以下を除きます。
エンコードされない |
|
encodeURIとは対照的に、URLやファイル名で重要な文字もエンコードされます。したがって、この関数を使用して、任意のテキストを合法的なファイル名またはURLパスセグメントに変換できます。例えば
> encodeURIComponent('http://example.com/Für Elise/')
'http%3A%2F%2Fexample.com%2FF%C3%BCr%20Elise%2F'decodeURI(encodedURI)
encodeURIによって生成されたパーセントエンコードされたURIをデコードします。
> decodeURI('http://example.com/F%C3%BCr%20Elise/')
'http://example.com/Für Elise/'encodeURIはURI文字をエンコードせず、decodeURIは正しくエンコードされていてもURI文字をデコードしません。
> decodeURI('%2F')
'%2F'
> decodeURIComponent('%2F')
'/'decodeURIComponent(encodedURIComponent)
encodeURIComponentによって生成されたパーセントエンコードされたURIコンポーネントをデコードします。decodeURIとは対照的に、すべてのパーセントエンコードされた文字がデコードされます。
> decodeURIComponent('http%3A%2F%2Fexample.com%2FF%C3%BCr%20Elise%2F')
'http://example.com/Für Elise/'以下は非推奨です。
escape(str) は str をパーセントエンコードします。非ASCII文字を適切に処理しないため、非推奨です。encodeURIComponent() を代わりに使用してください。unescape(str) は str をパーセントデコードします。非ASCII文字を適切に処理しないため、非推奨です。decodeURIComponent() を代わりに使用してください。以下のメソッドは、数値の分類と解析に役立ちます。
isFinite(number) (無限大の確認)isNaN(value) (落とし穴:値がNaNかどうかを確認する)parseFloat(string) (parseFloat())parseInt(string, radix) (parseInt()による整数)このセクションでは、JavaScriptでコードを動的に評価する方法を調べます。
関数呼び出し:
eval(str)
str内のJavaScriptコードを実行します。例えば
> var a = 12;
> eval('a + 5')
17eval()はステートメントコンテキストで解析することに注意してください(式と文を参照)。
> eval('{ foo: 123 }') // code block
123
> eval('({ foo: 123 })') // object literal
{ foo: 123 }eval()では、厳格モードを使用する必要があります(厳格モードを参照)。ゆるいモードでは、評価されたコードは周囲のスコープにローカル変数を作成できます。
functionsloppyFunc(){eval('var foo = 123');// added to the scope of sloppyFuncconsole.log(foo);// 123}
厳格モードではそれは起こりません。
functionstrictFunc(){'use strict';eval('var foo = 123');console.log(foo);// ReferenceError: foo is not defined}
しかし、厳格モードでも、評価されたコードは周囲のスコープの変数への読み書きアクセス権を持っています。このようなアクセスを防止するには、eval()を間接的に呼び出す必要があります。
eval()を呼び出すには2つの方法があります。
call()を介して、windowのメソッドとして、別の名前で保存してそこで呼び出すなど)。既に見たように、直接的なeval()は現在のスコープでコードを実行します。
varx='global';functiondirectEval(){'use strict';varx='local';console.log(eval('x'));// local}
逆に、間接的なeval()はグローバルスコープで実行します。
varx='global';functionindirectEval(){'use strict';varx='local';// Don’t call eval directlyconsole.log(eval.call(null,'x'));// globalconsole.log(window.eval('x'));// globalconsole.log((1,eval)('x'));// global (1)// Change the name of evalvarxeval=eval;console.log(xeval('x'));// global// Turn eval into a methodvarobj={eval:eval};console.log(obj.eval('x'));// global}
(1)の説明:変数を参照すると、最初の結果は、いわゆる参照、2つの主要なフィールドを持つデータ構造になります。
baseは環境を指し、変数の値が格納されているデータ構造です。referencedNameは変数の名前です。eval()関数の呼び出し中、関数呼び出し演算子(括弧)はevalへの参照に遭遇し、呼び出す関数の名前を決定できます。したがって、このような関数呼び出しは直接的なeval()をトリガーします。しかし、演算子に参照を渡さないことで、間接的なeval()を強制することができます。それは、演算子を適用する前に参照の値を取得することで実現されます。(1)行のコンマ演算子がそれを行います。この演算子は最初のオペランドを評価し、2番目のオペランドの評価結果を返します。評価は常に値を生成するため、参照は解決され、関数名は失われます。
間接的に評価されたコードは常にゆるいです。これは、コードが現在の周囲とは独立して評価されるという結果です。
functionstrictFunc(){'use strict';varcode='(function () { return this }())';varresult=eval.call(null,code);console.log(result!==undefined);// true, sloppy mode}
コンストラクタFunction()は次のシグネチャを持っています。
newFunction(param1,...,paramN,funcBody)
これは、ゼロ個以上のパラメータの名前がparam1、parem2などであり、本体がfuncBodyである関数を作成します。つまり、作成された関数は次のようになります。
function(«param1»,...,«paramN»){«funcBody»}
パラメータの合計を返す関数fを作成するためにnew Function()を使用しましょう。
> var f = new Function('x', 'y', 'return x+y');
> f(3, 4)
7間接的なeval()と同様に、new Function()はスコープがグローバルである関数を生成します。[18]
varx='global';functionstrictFunc(){'use strict';varx='local';varf=newFunction('return x');console.log(f());// global}
このような関数は、デフォルトでゆるい関数でもあります。
functionstrictFunc(){'use strict';varsl=newFunction('return this');console.log(sl()!==undefined);// true, sloppy modevarst=newFunction('"use strict"; return this');console.log(st()===undefined);// true, strict mode}
通常は、コードを評価するためにeval()よりもnew Function()を使用する方が良いでしょう。関数パラメータは評価されたコードへの明確なインターフェースを提供し、評価されたコードがグローバル変数(およびそれ自身の変数)のみにアクセスできるようにするために、間接的なeval()のわずかにぎこちない構文は必要ありません。
eval()とnew Function()は避けるべきです。コードを動的に評価することは遅く、潜在的なセキュリティリスクです。また、静的解析を使用するほとんどのツール(IDEなど)がコードを考慮することを妨げます。
多くの場合、より良い代替案があります。例えば、Brendan Eichは最近、ツイートで、名前が変数propNameに格納されているプロパティにアクセスしたいプログラマーによって使用されるアンチパターンについて述べました。
varvalue=eval('obj.'+propName);
その考えは理にかなっています。ドット演算子は固定された静的に提供されるプロパティキーのみをサポートします。この場合、プロパティキーは実行時にのみ知られるため、その演算子を使用するにはeval()が必要です。幸いなことに、JavaScriptにはブラケット演算子もあり、動的なプロパティキーを受け入れます。したがって、以下は前述のコードのより良いバージョンです。
varvalue=obj[propName];
また、JSONデータの解析にeval()またはnew Function()を使用しないでください。それは安全ではありません。ECMAScript 5のJSONに対する組み込みサポート(第22章を参照)に依存するか、ライブラリを使用してください。
eval()とnew Function()には、高度ではありますが、正当なユースケースがいくつかあります。関数を含む構成データ(JSONでは許可されていません)、テンプレートライブラリ、インタープリタ、コマンドライン、モジュールシステムなどです。
これは、JavaScriptでのコードの動的な評価に関する比較的ハイレベルな概要でした。さらに詳しく調べたい場合は、kangaxによる記事“Global eval. What are the options?”をご覧ください。
ほとんどのJavaScriptエンジンには、ログ出力とデバッグのためのメソッドを持つグローバルオブジェクトconsoleが存在します。このオブジェクトは言語自体の一部ではありませんが、事実上の標準となっています。consoleメソッドの主な目的はデバッグであるため、開発中は頻繁に使用されますが、デプロイされたコードではほとんど使用されません。
このセクションでは、コンソールAPIの概要を示します。Chrome 32、Firebug 1.12、Firefox 25、Internet Explorer 11、Node.js 0.10.22、Safari 7.0時点の現状を記述しています。
コンソールAPIの実装は大きく異なり、常に変化しています。権威のあるドキュメントが必要な場合は、2つの選択肢があります。まず、APIの標準のような概要を参照できます。
第二に、様々なエンジンのドキュメントを参照できます。
Internet Explorer 9にはバグがあります。このブラウザでは、開発者ツールが少なくとも一度開かれていた場合のみconsoleオブジェクトが存在します。つまり、consoleを参照してツールが事前に開かれていない場合、ReferenceErrorが発生します。回避策として、consoleが存在するかどうかをチェックし、存在しない場合はダミーの実装を作成できます。
コンソールAPIには、次のログ出力メソッドが含まれています。
console.clear()
console.debug(object1, object2?, ...)
console.log()を使用することをお勧めします。console.error(object1, object2?, ...)
console.exception(errorObject, object1?, ...]) [Firebug限定]object1などをログ出力し、インタラクティブなスタックトレースを表示します。console.info(object1?, object2?, ...)
console.log(object1?, object2?, ...)
パラメータをコンソールに出力します。最初の引数がprintfスタイルのフォーマット文字列である場合、それを使用して残りのパラメータを出力します。例(Node.js REPL)
> console.log('%s', { foo: 'bar' })
[object Object]
> console.log('%j', { foo: 'bar' })
{"foo":"bar"}唯一確実にクロスプラットフォームで動作するフォーマットディレクティブは%sです。Node.jsはJSONとしてデータをフォーマットするための%jをサポートしていますが、ブラウザはコンソールに何かインタラクティブなものをログ出力するディレクティブをサポートする傾向があります。
console.trace()
console.warn(object1?, object2?, ...)
様々なプラットフォームでのサポートは次の表に示されています。
| Chrome | Firebug | Firefox | IE | Node.js | Safari | |
| ✓ | ✓ | ✓ | ✓ | ||
| ✓ | ✓ | ✓ | ✓ | ✓ | |
| ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| ✓ | |||||
| ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
exceptionは、単一のプラットフォームでのみサポートされているため、斜体で表記されています。
コンソールAPIには、次の確認とカウントのメソッドが含まれています。
console.assert(expr, obj?)
exprがfalseの場合、objをコンソールに出力し、例外をスローします。trueの場合は何も行いません。console.count(label?)
様々なプラットフォームでのサポートは次の表に示されています。
| Chrome | Firebug | Firefox | IE | Node.js | Safari | |
| ✓ | ✓ | ✓ | ✓ | ✓ | |
| ✓ | ✓ | ✓ | ✓ |
コンソールAPIには、フォーマットされたログ出力のための次のメソッドが含まれています。
console.dir(object)
console.dirxml(object)
console.group(object1?, object2?, ...)
console.groupEnd()を呼び出すことでブロックを閉じます。ブロックは最初は展開されていますが、折りたたむことができます。console.groupCollapsed(object1?, object2?, ...)
console.group()と同様に動作しますが、ブロックは最初は折りたたまれています。console.groupEnd()
console.group()またはconsole.groupCollapsed()で開かれたグループを閉じます。console.table(data, columns?)
配列をテーブルとして出力します。要素ごとに1行です。オプションのパラメータcolumnsは、どのプロパティ/配列インデックスが列に表示されるかを指定します。このパラメータが指定されていない場合、すべてのプロパティキーがテーブル列として使用されます。欠落しているプロパティと配列要素は、列にundefinedとして表示されます。
varpersons=[{firstName:'Jane',lastName:'Bond'},{firstName:'Lars',lastName:'Croft',age:72}];// Equivalent:console.table(persons);console.table(persons,['firstName','lastName','age']);
結果のテーブルは以下のようになります。
| (インデックス) | firstName | lastName | age |
0 | “Jane” | “Bond” | undefined |
1 | “Lars” | “Croft” | 72 |
様々なプラットフォームでのサポートは次の表に示されています。
| Chrome | Firebug | Firefox | IE | Node.js | Safari | |
| ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| ✓ | ✓ | ✓ | ✓ | ||
| ✓ | ✓ | ✓ | ✓ | ✓ | |
| ✓ | ✓ | ✓ | ✓ | ✓ | |
| ✓ | ✓ | ✓ | ✓ | ✓ | |
| ✓ | ✓ |
コンソールAPIはプロファイリングとタイミングのための次のメソッドを含みます。
console.markTimeline(label) [Safari限定]console.timeStampと同じです。console.profile(title?)
titleはプロファイルレポートに使用されます。console.profileEnd()
console.time(label)
labelのタイマーを開始します。console.timeEnd(label)
labelのタイマーを停止し、開始以降経過した時間を表示します。console.timeStamp(label?)
labelでタイムスタンプを出力します。コンソールまたはタイムラインに出力される場合があります。様々なプラットフォームでのサポートは次の表に示されています。
| Chrome | Firebug | Firefox | IE | Node.js | Safari | |
| ✓ | |||||
| ✓ | ✓ | (開発者ツール) | ✓ | ✓ | |
| ✓ | ✓ | (開発者ツール) | ✓ | ✓ | |
| ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| ✓ | ✓ |
markTimelineは、単一のプラットフォームでのみサポートされているため、斜体で表記されています。 (開発者ツール)という指定は、メソッドを機能させるために開発者ツールを開く必要があることを意味します。[19]
次のグローバル変数は、関数の名前空間として機能します。詳細については(括弧内に示されている資料を参照してください:
JSON
Math
Object
次のグローバル変数は、特殊な値を含んでいます。それらについては、(括弧内に示されている資料を参照してください:
undefined
存在しないことを示す値(undefinedとnull)
> ({}.foo) === undefined
trueNaN
「数値ではない」ことを示す値(NaN)
> 1 / 'abc' NaN
Infinity
数値無限大∞を示す値(Infinity)
> 1 / 0 Infinity