続・先取り! Google Chrome Extensions
第8回 Google Chrome拡張とHTML5 #2
こんにちは,太田です。今回はGoogle Chrome拡張に使えるHTML5関連技術の2回目をお送りします。
前回はcanvas,ドラッグ・アンド・ドロップを取り上げましたが,今回はHTML5周辺の技術として,ECMAScript 5やCSS3の先行実装を取り上げます。ECMAScript 5は昨年末(2009年12月)にリリースされたばかりですが,WebKit・Chromiumでは早速(実際にはかなり先行して)その実装が進められています。またCSS3についても,多くのモジュールがWorking Draft(草案)の段階ですが,WebKitでは先行実装がされており,Chrome拡張ではその機能を存分に試すことができます。前回も書きましたが,Chrome拡張はそういった最新技術を試すのに格好のプラットフォームです。
Chrome拡張で使えるECMAScript 5
Google ChromeのJavaScriptエンジンはGoogle製のV8ですが,V8はWebKit(Safari)のJavaScriptCoreとの互換性を意識して実装が進められています。そのため,多くのECMAScript APIはJavaScriptCoreで実装されたらV8にも実装されるという流れを踏んでいます。JavaScriptCoreでのECMAScript 5の実装状況はQt Labs Blogs ≫ ECMAScript 5 and WebKit/JavaScriptCoreで,V8についてはECMAScript 5 and Chromium/V8 - 0xFFでまとめられています。
Native JSON
まず,なんといってもECMAScript 5ではJSONが正式にサポートされた点が大きなニュースです。JSONをサポートするプログラミング言語が増えてきた昨今,ECMAScript発であるJSONを今ごろになってECMAScriptが正式にサポートというのは少々驚かれるかもしれません(それだけECMAScriptの改訂が止まっていた,と言えます)。
JavaScriptにおけるJSONのメソッドは,JSON.stringifyとJSON.parseの2つだけです。
JSONのメソッド
var data = {
a:1,
b:[1,2],
c:new Date(),
f:function(a){return a;}
};
var json_text = JSON.stringify(data);
console.log(json_text);
//{"a":1,"b":[1,2],"c":"2010-01-18T14:01:36Z"}
var json_text2 = JSON.stringify(data,null,2);
console.log(json_text2);
/*
{
"a": 1,
"b": [
1,
2
],
"c": "2010-01-18T14:01:36Z"
}
*/
JSON.stringifyは第一引数に渡したオブジェクトをJSON文字列に変換するメソッドです。第3引数に数値を渡すとその数値だけインデントさせることができます。第3引数には文字列を持たすこともできるので,\tを渡せばタブインデントさせることも可能です。
JSONメソッドの第2引数
function replacer(key, value) {
if (this[key] instanceof Date) {
return this[key].getTime();
} else if (this[key] instanceof Function) {
return this[key].toString();
} else {
return value;
}
}
var json_text3 = JSON.stringify(data, replacer,'\t');
console.log(json_text3);
/*
{
"a": 1,
"b": [
1,
2
],
"c": 1263823296890,
"f": "function (a){return a;}"
}
*/
var data2 = JSON.parse(json_text);
console.log(data2);
JSON.stringifyの第2引数には関数を渡すことで(主にイレギュラーなデータの扱いについて)出力をカスタマイズすることができます。上記のreplacerの例のように,日付をミリ秒で出力したり,通常は無視されてしまう関数を文字列として出力するといったことが可能です(なお,余談ですがFirefox3.5ではstringifyの第2引数についてバグがあるため,意図通りの結果を得られません cf:Bug 512447)。
また,オブジェクトのtoJSONメソッドを書き換えることで,特定のオブジェクトについて出力をコントロールすることも可能です(ただし,この機能のためprototype.jsを読み込んだ環境でJSON.stringfyを使用すると意図しない結果になってしまう現象が起こるので注意が必要です)。
JSON.parseはJSON文字列をJavaScriptのオブジェクトに変換します。第2引数はやはり出力をカスタマイズすることができるので,上記replacerの逆の処理を行うことで柔軟にオブジェクトをやり取りすることができるようになります。
なお,このJSONですが,JavaScriptの感覚で書こうとすると必ずと言っていいほど正しくないJSONを書いてしまいます。JavaScriptでのオブジェクトの表記法は曖昧さを許容するゆるい仕様ですが,データ記述言語としてのJSONは曖昧さを許さないためです。特に間違いやすいのは,文字列を囲むときにダブルクォートを使用しなければいけない(シングルクォートは使えない)点,キーもダブルクォートで文字列として表記しないといけない点の2つです。JSONは手で書くのではなく,ライブラリやJSON.stringifyで出力させるのがよいでしょう。
Array拡張
配列メソッドとしてindexOf, lastIndexOf, every, some, forEach, map, filter, reduce, reduceRightが追加されています。indexOf, lastIndexOfは配列を検索し,最初に一致した添字を返すメソッドです。それ以外のメソッドはforEachに代表されるように,配列の各要素を順番に処理するメソッドで,それぞれ結果の扱い方が少しずつ異なります。
Array.forEach
var list = [1,2,3];
list.forEach(function(item, i, array){
console.log(item);
});
このArray拡張はFirefoxでは1.5からサポートされていますし,Google Chromeもリリース当初からサポートしているメソッドで,prototype.jsなどのライブラリで同種のメソッドが古くから実装されてるので,すでに定番となっていると言えます。


