WIZ-CODE.blog

JavaScriptやAjaxをテーマとしたブログです。

*

軽量JavaScriptライブラリ「jPrim」ジェイプリム

   

現在ツイッター関係と同時進行でJavaScriptライブラリを作っています。いつかはJavaScriptライブラリを作成したいと思っていたので、念願がかなった次第です(まだ未完成ですが)。 ライブラリの作成で参考にしたのはこの書籍です。 JavaScriptパターン ―優れたアプリケーションのための作法 ライブラリの設計をどうすべきかといった問題に対してヒントを与えてくれます。 jQueryPrototypeのような巨大なライブラリを個人で作るのはさすがに不可能ですが(といいつつもuupaa.jsって個人で作ってますね……)、ニッチな分野に特化していけば個人でもそれなりのものは作れると考えました。 現在制作中のライブラリには、jPrim(ジェイプリム)という名前をつけました。 ⇒jPrim.js(ベータ版公開中) 名前はかわいいですが、由来はプリミティブからです。JavaScriptの三種類のプリミティブ値(数値、文字列、真偽値)の使い勝手を高めることを目的としています。普段あまり使われないラッパーオブジェクトである、NumberStringBooleanを用いています。ただしプロトタイプの拡張はしません。jQueryのように値をラップしてオブジェクトを作ります。 使い方の一例を見ていきます。数値を扱うオブジェクトを作成するとして、次のようにコードを書きます。

 
var number1 = jPrim(10);
 

このようにjPrimメソッドにプリミティブ値を渡します。この例では数値の10を渡しました。渡すデータ型によって自動で判別して相応しいオブジェクトを作ります。それでは次にこのオブジェクトを参照する変数number1で何ができるかを見ていきます。

 
console.log( number1.add(10) ); // 20とコンソールに出力される
 

console.log()はJavaScriptコンソールでデータを確認する便利なメソッドです。ただしFirefoxのFirebugアドオンなどをインストールしておかないといけません。上のコードではjPrimaddメソッドを実行してその結果(return値)をコンソールに表示するようにしています。addメソッドは足し算を行います。jPrimの初期化で10の値を指定していたので、結果は20となります。 なぜ四則演算をわざわざメソッドを経由して行うかですが、jPrimjQueryのメソッドチェーンに似た仕組みを使っています。つまり、ドットシンタックスでメソッドをつなげることで、連続的に計算を行うことができます。また、出力された値が数値なのにメソッドチェーンが続くのは、これらのメソッドが返す値がプリミティブ値ではなく、数値や文字列のラッパーオブジェクトだからです。

 
console.log( number1.add(10).multiply(5) ); // 100とコンソールに出力される
 

multiplyメソッドは引数の値で掛け算を行います。掛け算をする前にすでに20という値が出ていたので、multiplyメソッドで5をかけた結果は100になります。四則演算に対応してsubtractメソッド(引き算)とdivideByメソッド(割り算)も用意していますが、それぞれ負数と逆数をaddメソッドとmultiplyメソッドに与えれば同じ結果になります。なお。数値計算に関わるその他のメソッドは次のようなものです。 limitメソッド……引数に最小数、最大数を指定して、数値をこれらの範囲内に収めます。 modメソッド……引数の値で割ったときの余りを求めます。 powメソッド……引数の値のべき乗数を求めます。Math.powを使います。 rootメソッド……引数の値の累乗根を求めます。これも実際にはMath.powを使います。 sqrtメソッド……平方根を求めます。 ここから少し特殊な使い方になります。 fibonacciメソッド……フィボナッチ数列の第n項を計算します。 progressionメソッド……数列の第n項を計算します。等差数列か等比数列を選択可能です。 summationメソッド……数列の和を計算します。等差数列か等比数列を選択可能です。 accumulatorメソッド……Prototype.jsライブラリのinjectメソッドと同じく、初期値に計算結果を加算し累積させていきます。 loopメソッド……これもPrototype.jsライブラリのtimesメソッドに似た機能です。jPrimオブジェクトの現在値の分だけループ処理をします。 timerメソッド……loopメソッドに似ていますが、こちらは指定した時間間隔で処理をくり返すメソッドです。 これらのメソッドのうちsummationメソッドを使って、1から10の数字を足し合わせる学校で教わった計算をしてみます。summationメソッドの第1引数に足し合わせる回数を入れ、第2引数に各項との差(公差)を渡します。

 
//setValueメソッドはjPrimオブジェクトの値を指定する
console.log( number1.setValue(1).summation(10, 1) ); // 55とコンソールに出力される
 

ここでjPrimの特徴というか欠点を指摘しておきます。それは、一度メソッドチェーンを切ると、jPrimオブジェクトの値が一番最初に設定した値に戻ってしまうということです。 たとえば、次の例を見るとコンソールに表示される数値は100となりそうなのですが、上の行で一度チェーンが切れているため、jPrimメソッドで初期化された際の10になってしまいます。

 
var number1 = jPrim(10); // 初期値10でjPrimオブジェクトを作成
number1.add(10).multiply(5); // 計算結果は100。ここでいったんチェーンが切れる

console.log( number1 ); // コンソールに100が出力されると期待されるが、実際には10と出力される
 

ただし、最後に計算した結果はキャッシュされていて、次のようにrefreshメソッドで呼び出すことで、最新の計算値を取り出すことができます。

 
var number1 = jPrim(10);
number1.add(10).multiply(5);

var number2 = number1.refresh(); // 変数number2に最後の計算結果を代入する

console.log( number1 ); // 変数number1は元の10のままだが、
console.log( number2 ); // 100と出力される。変数number2は最後の計算結果が出力される。
 

数値関連の実装は現段階でこのようなものです。次に文字列の実装を見ていきたいところですが、こちらはまだ残念ながらほとんど実装が進んでいません。文字列の両端の空白を除去する、有名ライブラリに欠かせないtrimメソッドと、あと一つは完全にネタ的なものとしてcensor(検閲)メソッドを実装しています。とりあえずこのcensorメソッドの使い方だけを見ていきましょう。

 
var str1 = jPrim('     ヒトラーとスターリン、毛沢東は20世紀を代表する独裁者と言われている。   ');
 

このような形に、わざと前後に空白を残したテキストを用意して、jPrimメソッドで初期化します。次に検閲対象のキーワードを決めます。「ヒトラー」「スターリン」「毛沢東」「独裁者」の四つがどうもヤバそう(笑)なので、これらを削除することにします。

 
//trimメソッドで前後の空白を削除し、その後censorメソッドで都合の悪い単語を削除する
//getValueメソッドは確実にプリミティブ値として出力したいときに使う。一方でメソッドチェーンは切れる
console.log( str1.trim().censor('ヒトラー|スターリン|毛沢東|独裁者').getValue() );
 

出力結果は次のようになります。

 
****と*****、***は20世紀を代表する***と言われている。
 

このcensorメソッドはまず、第1引数に検閲する単語を渡します。文字列で渡す場合は、文字列か配列に、もしくは正規表現リテラルを渡します。なお、このメソッドは多機能で(笑)、削除箇所の置き換え文字を指定することができます。デフォルトでは「*」となっているので、第2引数に希望する置き換え文字を入れます。

 
// 正規表現に詳しくない場合は配列が便利
console.log( str1.trim().censor( [ 'ヒトラー', 'スターリン', '毛沢東', '独裁者' ], '●' ).getValue() );

// もちろん正規表現リテラルも使える
console.log( str1.trim().censor( /ヒトラー|スターリン|毛沢東|独裁者/gi, '×' ).getValue() );
 

二つの出力結果は次のようになります。

 
●●●●と●●●●●、●●●は20世紀を代表する●●●と言われている。
××××と×××××、×××は20世紀を代表する×××と言われている。
 

さらに、第2引数を二文字以上にすると、定型文句で置き換えることができます。少し長いですが次の文章の検閲キーワードを定型文句で置き換えてみます。

 
 
var str2 = jPrim('ヒトラーとスターリン、毛沢東は20世紀を代表する独裁者と言われている。ヒトラーはユダヤ人を数百万人虐殺し、スターリンは自国民を含めて数千万人を虐殺した。毛沢東は故意の虐殺よりも政策の失敗で結果的に多くの人民を餓死させたと見られている。その犠牲者数は大躍進政策から文化大革命に至る約20年のあいだに数千万人を数えるという。');

console.log( str2.censor( [ '毛沢東', '独裁者', '虐殺', '失敗', '餓死', '犠牲者', '大躍進政策', '文化大革命' ], '【削除済み】' ).getValue() );
 

そして出力結果は……

 
 
ヒトラーとスターリン、【削除済み】は20世紀を代表する【削除済み】と言われている。ヒトラーはユダヤ人を数百万人【削除済み】し、スターリンは自国民を含めて数千万人を【削除済み】した。【削除済み】は故意の【削除済み】よりも政策の【削除済み】で結果的に多くの人民を【削除済み】させたと見られている。その【削除済み】数は【削除済み】から【削除済み】に至る約20年のあいだに数千万人を数えるという。
 
 

某大陸国家にとって都合の悪い単語が見事に除去されました(笑)。 とまあ、何の役に立つのかみたいなところがありますが、今後は実用的なメソッドを逐次入れていくつもりです。何か他に面白いアイデアなどありましたら募集していますので。コメントやメールなどにてよろしくお願いします。

 - JavaScript/Ajax , ,