はじめに
- JavaScript stage 0,1,2,3 Advent Calendar 2015 の記事です
- System.globalを紹介します
- 記事執筆時で stage1 の仕様です
これはなに
JS実行環境によってまちまちな名前を付けられている the global object (グローバルオブジェクト)をどんな環境でも一意の名前で取得できるようにするためのものです。
System.global;
※「グローバルオブジェクト(the global object)」はDate
とかの組み込みオブジェクトである「グローバルオブジェクト(global objects)」とは異なります。グローバル変数の全てを自分のプロパティとしてもつ特殊なオブジェクトの方です。日本語にすると同じになってしまうのでややこしいですが、この記事では以後前者を指します。
ES2015以前
window
,self
,flame
,global
,d8
,jsc
...環境によってまちまちの名前で取得可能でした。そのためコードの可搬性が低くなってしまっていました。
グローバルオブジェクトを簡単に取得できるイディオムとして知られていたのは次のコードです。
var g = Function("return this")();
参考;[JavaScript] グローバル変数とグローバルオブジェクトを取得する方法
ところがChromeAppで実行する場合、CSP(コンテンツセキュリティポリシー)違反を起こすコードになってしまい使用不可能でした。proposalのページでも紹介されている es6-shim では以下のようなコードでそれを回避しています。
var getGlobal = function () {
// the only reliable means to get the global object is
// `Function('return this')()`
// However, this causes CSP violations in Chrome apps.
if (typeof self !== 'undefined') { return self; }
if (typeof window !== 'undefined') { return window; }
if (typeof global !== 'undefined') { return global; }
throw new Error('unable to locate global object');
};
今後JSの実行系が増え、IoTなどでも使われるようになる場面が増えた場合、グローバルオブジェクトがどのような名前になるかわかりません。あらたな環境が増えるたびに、上記の泥臭いコードを書き換えてゆくのは得策ではありません。
ES.nextでは
どんな環境が増えようとも同じ名前で取得できるようにしよう、というのがSystem.global
です。この名前ならば、将来どんな箇所でJSを動かそうともグローバルオブジェクトが確実に取得できるようになり、コードの可搬性が上がる上にメンテナンスする必要も無くなります。
ECMAScriptは今後、毎年アップデートされていく予定だそうなので、新仕様への対応が各実行系で今以上にバラバラになっていく事が予想されます。下位互換を維持するpolyfillは有効ですが、大半の場合グローバルオブジェクトに手を入れて新しい仕様に手を入れていく事になると思われるため、polyfillが書きやすくなるSystem.global
はES.nextの随時アップデートのためにも重要だと言えるでしょう。
注意点
polyfillが用意されているのですが、ページで指摘されている問題点のFunction("return this")()
が使われているコードのため、ChromeAppで使えません。あるいみこれ以上無いサンプルケースになっていますが、一体なぜなんでしょうか。
stage1なので名称もこの名前になるかすらも分かりません。かつてES4という規格を丸ごと闇に葬り去った実績があるのでECMAScriptの未来絵図はあまり信用せず、現時点では話半分に見ておくのがいいと思います。