タグ一覧
プロフィール
Feed
次の記事
サーバーサイドJavaScriptで簡単Webアプリ開発 - スタート編
前の記事
ScalaとMecabで形態素解析を行いコンソールに自動Tagリストを作る
  • JavaScriptにJavaのようなequalsメソッドを作成する
    JavaScript

    02
    May
    2011
    JavaScript
    このエントリーをはてなブックマークに追加
    この記事をLivedoorクリップ!
    Evernoteにclipする

    JavaScriptでは等価比較を行う際に、== 、=== の2種類のequalによる比較演算子が用意されており、== の方は、型はチェックせず値が正しいかどうかの判断しかせず、 === の方は型をチェックして値の比較演算を行いますよね。=== の方はより厳密な演算子で、JavaScriptのテクニック本でも === の使用を進めています。 (※PHPでも同じ比較演算子が導入されています。)

    var data = "";
    
    // 0でもマッチしてしまう! 
    if (data == 0) {
      console.log("Match"); 
    }
    
    // これだとマッチしないからGood
    if (data === 0) {
      console.log("Match"); 
    }
    

    このようにequalの数(2個と3個)によって処理がかわるというのは、ミスを誘因しやすく、それによりBugの原因になったりする危険性があるので、不満がありました。構文チェックツール(JSLint)でチェックして、equalのミスコードをチェックするというのも手なのですが、頻繁にチェックするのは面倒です。そもそも間違いやすい比較演算子が問題なんだと思っています。。。(汗)そこでJavaでの等価比較メソッドである、equalsメソッドと同じようなJavaScript用のequalsメソッドを作成することにしました。 === とコーディングする箇所を誤って == としてしまったりするのは人間である以上、起こりえるものなので、別の名称のメソッドを用意して、イージミスを防ぎ素敵なJavaScriptライフを送りたいと思います。

    期待する実装形式は下記の感じです

    data1の型とdata2型の厳密比較演算を行いたい!

    if (data1.equals(data2)) {
      // なんらかの処理
    }
    

    equalsメソッドの実装内容

    個人的によく使用するStringオブジェクトのprototype chainに実装してみます。まずは、this == paramで値の比較を行います。そこで値が同じであれば、次に同じstring型かどうかを、typeof演算子で型のチェックを行います。特に目新しいコードでもなく、普通です。。。

    String.prototype.equals = function(param) {
      if (this == param) {
        return (typeof param === "string" ? true : false);
      }
      return false;
    };
    

    Stringオブジェクトのprototype chainの実装部分でthis === paramと行ったほうが単純そうに思うかもしれませんが、thisはobject型ですので、期待通りの動作はしません。

    String.prototype.equals = function(param) {
      return (this === param ? true : false);
    };
    
    thisとparamがマッチすることはなく、永遠にfalseがかえってしまいます

    Rhinoベースでの環境ではちょっと注意が必要

    Rhino1.7の環境で確認したのですが、RhinoやRhinoベースのサーバーサイドJavaScriptの環境では、すでにequalsメソッドが存在しているので注意が必要です。動作的には == 比較演算子と同じ、値の比較しか行いません。実際にRhino1.7のソースを解析した結果を晒しますと、下記になります。

    src/org/mozilla/javascript/NativeString.javaを参照
    このlineの前後に、巨大なswitch case文があり、Rhinoで使用可能なStringオブジェクトのメソッドが定義されています。line:190にequalsメソッドを確認できます
    (1) org.mozilla.javascript.NativeScript line: 190
      ・
      ・
    case Id_link:  arity=0; s="link";  break;
    case Id_anchor:  arity=0; s="anchor";  break;
    <b>case Id_equals:  arity=1; s="equals";  break;</b> 
    case Id_equalsIgnoreCase:  arity=1; s="equalsIgnoreCase";  break;
    case Id_match:  arity=1; s="match";  break;
      ・
      ・
    

    このlineではequalsメソッドの実装内容が記述されています。しかしScriptRuntime.toStringで値を全て、JavaのString型に変換してしまっているので、型の比較は行ってくれません

    (2) org.mozilla.javascript.NativeScript line: 367〜374
    
    case Id_equals:
    case Id_equalsIgnoreCase: {
      String s1 = ScriptRuntime.toString(thisObj);
      String s2 = ScriptRuntime.toString(args, 0);
      return ScriptRuntime.wrapBoolean(
      (id == Id_equals) ? s1.equals(s2) : s1.equalsIgnoreCase(s2));
    }
    


    コメントを書く
      • 投稿する
      • 確認する
    Powered by CoffeeBox、CoffeeScript、Node.js、MongoDB  Copyright (C) 深追い Fukaoi.org - Since 2007