2011年12月16日 15:00 [Edit]

javascript - そろそろECMAScript 5を使いたい少なくとも3つの理由

下準備も終わったので、本blogで扱うJavaScriptは、特に断りのない限りECMAScript 5を前提にしていくことにします。


0. どのブラウザーで使えるの?

以下で確認できます。

ECMAScript 5 compatibility table

ざっといろいろ試してみると…

  • IEは9以上以降かつStandard Modeなら使える
  • Safari 5はFunction.prototype.bindのみ使えない - 5.1.4より[native code]
  • iOS5も同様
  • Android 2.3ではさらに加えてObject.sealなどObjectをロックする機能が使えない

というわけで、もう使いはじめてもいいのではないか、と。

1. Array.prototype がまともに使える

特に Array.prototype.map がIEにないおかげでforループ使う羽目になったり手で Array.prototype.map を拡張したりするのにうんざりしていたというのは先日書いたとおりです。

それでも、Array.prototype は kriskowal/es5-shim を使うなど、いわゆる polyfilling でしのげるのですが、以下の二つはES5ならでないと出来ません。

2. Pure Objectが作れる

ES5以前のJavaScriptには「純粋なオブジェクト」は存在しませんでした。

var o = {};
p( 'hasOwnProperty' in {} );

それがどんな問題を引き起こすかは、「404 Blog Not Found:javascript - new Hash(); // Object はHashじゃないから」で触れたのですが、ES5なら純粋なオブジェクトはObject.create(null)で手に入ります。

var o = Object.create(null); /* voila! */
p( 'hasOwnProperty' in o );
p( 'toString' in o );
try {
    o[1] = 'one';
    p( o[1] );
    p( o );
}catch(e){
    p( e );
}

見てのとおり、そのままでは暗黙の文字列化すら例外を投げるほど純粋です。「本当のハッシュ」がこれで実現できます。

このことはまた、ES5の機能をshimで実現しているのか否かの判定にも使えそうです。

var shimmed = ('hasOwnProperty' in Object.create(null));
p(shimmed);

3. Object.prototypeすら安全に拡張できる

しかし私がES5で一番気に入っているのが、何と言ってもこれです。

それ以前は Object.prototype を拡張することは事実上の禁じ手でした。拡張したプロパティがenumerableになってしまい、inでそれが拾われてしまうからです。

Object.prototype.keys = function(){ return Object.keys(this) };
var o = {"one":1,"two":2,"three":3};
p(o.keys());
for (var k in o) { p( k + ':' + o[k] ) };
/* cleanup and make sure */
delete Object.prototype.keys;
p( Object.prototype.keys );

ES5以降は、以下のようにすればbuilt-inのように enumerable でないプロパティを定義できるようになります。

Object.defineProperty(Object.prototype, 'keys', {
  value:function(){ return Object.keys(this) }, /* does the trick! */
  enumerable:false,
  writable:true,
  configurable:true
});
var o = {"one":1,"two":2,"three":3};
p(o.keys());
for (var k in o) { p( k + ':' + o[k] ) };
p(["one","two",,"three"].keys());   /* works for array */
p((1).keys());                      /* no-op */
p("string".keys());                 /* array-like */
/* cleanup and make sure */
delete Object.prototype.keys;
p( Object.prototype.keys );

mofmof-js - mofmof mofmof - Google Project Hosting
JavaScript 創始者が想定した、本来の JavaScript の利用方法(Prototype 拡張)に立ち返り、Array.prototype, String.prototype, Number.prototype などを積極的に拡張しています

ES5ならObject.prototypeも「本来のJavaScriptの利用方法」で利用できるようになるわけです

「全てのES5以前のJS実装を、生まれる前に消し去りたい」

Dan the JavaScripter


この記事へのトラックバックURL