JavaScript/Global
グローバルオブジェクト
[編集]グローバルオブジェクトは組込みオブジェクトでブラウザ環境では window オブジェクトです。 例えば alert() メソッドの実体は、window.alert() です。 DOMが扱う対象の document も window.document です。 function f(){} とした場合のユーザーが定義した関数 f は window.f です。 このようにオブジェクトを指定しないで参照すると、グローバルオブジェクトのプロパティが参照されます。 ブラウザ環境以外では window はないので、 globalThis がグローバルオブジェクトになります。 ブラウザ環境でも globalThis がグローバルオブジェクトとして参照できます。
グローバルオブジェクトの値プロパティ
[編集]NaN
[編集]初出はES1[1]。
Infinity
[編集]初出はES1[2]。
グローバルオブジェクトの関数プロパティ
[編集]eval(x)
[編集]文字列を評価してその結果を返す。
eval関数の意味は、この一言で解説可能な単一の関数であるが実際には様々な役割があり非常に重要なのでさらに解説を行う。
eval関数は文字列をJavaScriptとして評価して、その結果を返す。 そのため
const str = "100"; const v = eval(str); // 数値100が、変数 v に代入される
とすると、その結果が返ってきます。 このことから、何らかのユーザーの入力があったときに、その結果をJavaScriptで扱える状態に変換可能です。 例えば、次のコードはHTMLで作成した、選択ボックスの結果を、evalでJavaScriptに変換した結果を逐次代入しています。
<form id="enquete"> <select id="yes-no"> <option value="true" selected="selected">はい</option> <option value="false">いいえ</option> </select> </form> <script> document.querySelector('#yes-no').onchange = e => { const target = e.currentTarget; const str = target[target.selectedIndex].value; const stat = eval(); console.log(stat); } </script>
(ただし入力紹介する結果が数値である場合は、後で紹介するparseIntやparseFloatの方が安全です)
さらに一歩推し進めて考えると、次の様に計算式等もeval関数は処理をして変数を参照できます。
console.log( eval('100+100') ); // 200を表示 var s='Hello'; eval('s +=",World!"'); console.log( s ); // Hello,World!を表示
ちなみにevalで呼び出せる変数の値は、グローバル変数(何処の関数のスコープにも属していない変数; 実体はグローバルオブジェクトのプロパティ)で無ければなりません。
ここまでを知っていると、eval関数はまた新たな使い道を考えることが出来ます。 外部から取り出したテキストを評価して、データとして取り出す手法です。
var s = '{ "住所":"東京都", "年齢":28, "性別":"男" }'; // 仮に外部から取り出したとしたデータ var o = eval('('+s+')'); // データを評価してJavaScriptデータに変換 console.log( o['年齢'] );
Webページ等で外部と通信しながら、その結果を動的反映していくAjaxという手法では、この手法を使って主にデータの取り出しを行っています。 この様に、JavaScriptのデータ形式を文字列化(シリアライズ)して、データのフォーマットとして使われ出しています。 この形式をJSON(JavaScript Object Notation)と言う。
実際には、コントロールされていない外部から文字列を受け取る場合には正しいJSONフォーマットではなく評価に失敗することがありうるため、エラーチェックのためにtry~catch文で囲う。
var o; try { o = eval('('+s+')'); } catch(e){ // エラー処理 }
- JavaScript Object Notation
eval関数はJavaScriptでの入力結果を何の疑問も持たず評価するため強力なゆえ危険で、「エラー処理に飛ばなかった=安全」とは言えません。
JSONフォーマットの文字列をeval関数で評価することで不正なコードを実行してしまう危険を侵さないよう、JSON オブジェクト がJavaScriptに加わり JSON.parse() でJSON(と期待される)文字列からJavaScriptのオブジェクトを JSON.stringify() でJavaScriptのオブジェクトからJSONフォーマットの文字列をそれぞれ得ることが出来るよになりました。
const str = JSON.stringify({ "住所":"東京都", "年齢":28, "性別":"男" }); console.log(str); // "{\"住所\":\"東京都\",\"年齢\":28,\"性別\":\"男\"}" const obj = JSON.parse(str); console.log(obj); // {"住所":"東京都","年齢":28,"性別":"男"}
数値処理関数
[編集]グローバルオブジェクトのメソッドは、いくつかの数値処理関数を標準で用意しています。 これらはNumberオブジェクトのメソッドの別名である場合と、機能的に近いものの挙動が違うものとがあるので注意が必要です。
parseInt(string , radix)
[編集]与えられた文字列を、先頭から解釈して整数に変換します。第2引数では、何進法とみなして変換を行うのかを指定します。 規格上、第2引数は省略した場合 0x で始まる16進法表記以外は10進法とみなして自動で変換を行っています。 Number.parseInt()の別名。
console.log( parseInt('10') ); // 10を表示 console.log( parseInt('10', 8 ) ); // 8を表示; 8進法として解釈、 console.log( parseInt('0x10') ); // 16を表示; 0xで始まる場合は16進数として解釈。 console.log( parseInt('0177') ); // 177を表示; 0で始まる場合も10進数として解釈。 ※ES5 0を前置する8進数表現は ES3 で非推奨、ES5で廃止 console.log( parseInt('0o77') ); // 0を表示; 0oで始まる場合も10進数として解釈。 console.log( parseInt('0b10') ); // 0を表示; 0bで始まる場合も10進数として解釈。 console.log( parseInt('ZERO') ); // 例外にならず NaN を表示; 1文字も数値として解釈できません。 console.log( parseInt('3_14') ); // 3 を表示; _ を区切り文字とする記法には対応しません。 console.log( Number.parseInt === parseInt ); // Number.parseInt の別名。true を表示
parseFloat(string)
[編集]与えられた文字列を、JavaScriptのNumber型のオブジェクトに変換します。 Number.parseFloat() の別名。
console.log( parseFloat('10') ); // 10が表示 console.log( parseFloat('10.00') ); // 10が表示 console.log( parseFloat('0x10') ); // 16進数としては評価されません。最初の数字の「0」まで表示 console.log( parseFloat('10e+4') ); // 1000を表示 console.log( parseFloat('10E-3') ); // 0.01を表示 console.log( parseFloat('Infinity') ); // Infinityを表示 console.log( parseFloat('-Infinity') );// -Infinityを表示 console.log( parseFloat('NaN') ); // NaNを表示 console.log( parseFloat('Text') ); // NaNを表示 console.log( parseFloat('9n') ); // 99を表示 console.log( typeof parseFloat('9n') );// bigint でなく number を表示 console.log( typeof eval('9n') ); // bigint を表示 console.log( Number.parseFloat === parseFloat ); // Number.parseFloat の別名。true を表示
isNaN(number)
[編集]引数の値がNaN(Not-a-Number)であればtrueを、それ以外はfalseを表示。 Number.isNaN() とは動作が異なります。
console.log( isNaN(NaN) ); // trueを表示 console.log( isNaN(Math.sqrt(-1)) ); // trueを表示 console.log( isNaN(Math.sqrt( Infinity/Infinity )) ); // trueを表示 console.log( Number.isNaN === isNaN ); // falseを表示; Number.isNaN ではない console.log( isNaN("NaN") ); // trueを表示; Stringからnumberに型変換され評価 console.log( Number.isNaN("NaN") ); // falseを表示; number でなければ false と即断
isFinite(number)
[編集]渡された値が有限数かどうかを判定します。
> 引数の値が±∞のいずれかであればfalseを、そうでない場合はtrueを返す。 > これは、通常の判別とtrueとfalseの結果が逆であるのに注意をする。
とありましたが、これはよくある間違いで isFinite(number) は無限大( Infinity )であるかを返すのではなく、有限数であるかを返します( Finite は英語で「有限な」)。
正あるいは負の Infinity か NaN か undefined の時 false を返し、それ以外は true を表示。
また、isFinite(number) と Number.isFinite() とでは動作が異なります。
console.log( isFinite(Infinity) ); // falseを表示 console.log( isFinite(100) ); // trueを表示 console.log( Number.isFinite === isFinite );// falseを表示 isFinite は Number.isFinite の別名ではない console.log( isFinite(null) ); // trueを表示; Stringからnumberに型変換され評価 console.log( Number.isFinite(null) );// falseを表示; number でなければ false と即断 console.log( isFinite("Infinity") ); // falseを表示; Stringからnumberに型変換され評価
URLエンコード関連関数
[編集]例えば次の様なリンクが存在したとしよう
http://ja.wikipedia.org/wiki/ネットスケープコミュニケーションズ
このリンクは日本語文字列を含んでいるため、実際にはURLとして利用できません。 そのため、これを英語と記号のASCII文字列の範囲の文字列で一度変換を行う必要があります。 これがURLエンコードと呼ばれる技術です。
どの文字コードを基準とのするかは、実装によるがJavaScriptは文字列がUTF8と考えて処理を行う。
実際にURLエンコードを行う関数にはencodeURIとencodeURIComponentの2つがあるが、これらは微妙に実装が違う。 実際に先ほどのURLをそれぞれの関数で変換してみます。
console.log( 'http://ja.wikipedia.org/wiki/ネットスケープコミュニケーションズ' ); console.log( encodeURI('http://ja.wikipedia.org/wiki/ネットスケープコミュニケーションズ') ); console.log( encodeURIComponent('http://ja.wikipedia.org/wiki/ネットスケープコミュニケーションズ') );
実行結果は次の様に表示された。
http://ja.wikipedia.org/wiki/ネットスケープコミュニケーションズ http://ja.wikipedia.org/wiki/%E3%83%8D%E3%83%83%E3%83%88%E3%82%B9%E3%82%B1%E3%83%BC%E3%83%97%E3%82%B3%E3%83%9F%E3%83%A5%E3%83%8B%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%BA http%3A%2F%2Fja.wikipedia.org%2Fwiki%2F%E3%83%8D%E3%83%83%E3%83%88%E3%82%B9%E3%82%B1%E3%83%BC%E3%83%97%E3%82%B3%E3%83%9F%E3%83%A5%E3%83%8B%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%BA
日本語文字列以外にも、スラッシュ(/)等の一部の文字がencodeURIComponentでは変換されているのが分かります。 これらの変換の結果は次の様な法則が共通しています。
- 文字の中でも[0-9][a-z][A-Z]の文字列は変換されない
- 日本語等の非ASCII文字列は基本的に変換される
なので、その外の記号文字列は変換結果の違うものなのでこれらを比較します。
無変換 ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~ encodeURI ! %22 # $ %25 & ' ( ) * + , - . / : ; %3C = %3E ? @ %5B %5C %5D %5E _ %60 %7B %7C %7D ~ encodeURIComponent ! %22 %23 %24 %25 %26 ' ( ) * %2B %2C - . %2F %3A %3B %3C %3D %3E %3F %40 %5B %5C %5D %5E _ %60 %7B %7C %7D ~
少し図が見づらいかもしれませんが、結果は一定の傾向があり、 encodeURIでは変換をされない文字は"#","/","&",":",";"等、URLで使用したり、CGIでパラメータを指定するときに特別な意味があるものです。
なので、これらの使い分けは次の様に分けるのが一つの基準となります。
- URLを変換するときはencodeURI
- データをcookieや外部のテキストとして出力するとき、CGIで入力された文字の安全な変換等はencodeURIComponent
このように変換した文字は、encodeURI、encodeURIComponentに対応するdecodeURI、decodeURIComponentという関数で元の文字列に戻すことができます。
encodeURI(uri)
[編集]URL(URI)として有効な範囲で、文字列をURLエンコードします。
// 変換して「JavaScript%E6%A8%99%E6%BA%96%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA」 encodeURI('JavaScript標準ライブラリ');
encodeURIComponent(uriComponent)
[編集]文字列をURLエンコードします。
// 変換して「JavaScript%E6%A8%99%E6%BA%96%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA」 encodeURIComponent('JavaScript標準ライブラリ');
decodeURI(encodedURI)
[編集]encodeURIで行った変換を元に戻す。
// 「JavaScript標準ライブラリ」に戻す encodeURI('JavaScript%E6%A8%99%E6%BA%96%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA');
decodeURIComponent(encodedURIComponent)
[編集]encodeURIComponentで行った変換を元に戻す
// 「JavaScript標準ライブラリ」に戻す encodeURI('JavaScript%E6%A8%99%E6%BA%96%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA');
コンストラクタ
[編集]標準組込みオブジェクトのコンストラクタは、ほとんどグローバルオブジェクトのメソッドです[3]。また多くは(newを伴わずに)型変換関数としても振る舞います。
この節は書きかけです。この節を編集してくれる方を心からお待ちしています。
- Error()
- 「Error」を参照
- EvalError()
- 「EvalError」を参照
- RangeError()
- 「RangeError」を参照
- ReferenceError()
- 「ReferenceError」を参照
- SyntaxError()
- 「SyntaxError」を参照
- TypeError()
- 「TypeError」を参照
- URIError()
- 「URIError」を参照
- Date()
- 「Date」を参照
- TypedArray
- 「TypedArray」を参照
- BigInt64Array()
- BigUint64Array()
- Float32Array()
- Float64Array()
- Int8Array()
- Int16Array()
- Int32Array()
- Uint8Array()
- Uint8ClampedArray()
- Uint16Array()
- Uint32Array()
-
- ArrayBuffer()
- SharedArrayBuffer()
- DataView()
- 「DataView」を参照
脚注
[編集]- ^ ECMA-262::19.1.3 NaN
- ^ ECMA-262::19.1.2 Infinity
- ^ TypedArrayの様な少数の例外はあります。