LoginSignup
58
50

More than 5 years have passed since last update.

is.javascript()?

Last updated at Posted at 2017-03-14

多種多様な「YesかNoか」判定を簡単に行えるis.jsを紹介するぞ。
なんと100以上の"is"が入っててわずか13KBだ。
確認したバージョンは0.8.0。

使用方法

npm install is_js --save

npmのインストールなどはこのあたりを参照のこと。

メソッド

特徴として、文法的に正しいかぎり、何を突っ込もうが必ずtrue|falseどちらかが返ってくる。
以下の例示は注釈のないかぎり返り値はtrue。


    // argumentsオブジェクトである
    is.arguments( function(){return arguments;}() );

    // 配列である
    is.array([1,2]);

    // bool値である
    is.boolean(false);

    // Dateオブジェクトである
    is.date(new Date());
    is.date(new Error()); // false

    // Errorオブジェクトである
    is.error(new Error());
    is.error(new Date()); // false

    // functionである
    is.function(function(){});

    // NaNである
    is.nan(NaN);

    // nullである
    is.null(null);
    is.null(undefined); // false

    // 数値である
    is.number(1);
    is.number(Number('1'));

    // Objectである
    is.object({});
    is.object(new Date());

    // JSONオブジェクトである
    is.json({});
    is.json(new Date()); // false

    // 正規表現リテラルである
    is.regexp(/reg/);
    is.regexp('/reg/'); // false

    // Stringリテラルである
    is.string('/reg/');
    is.string(/reg/); // false

    // Charである
    is.char('a'); // is.stringかつlength=1

    // undefinedである
    is.undefined(undefined);

    // 2引数が同じ型である
    is.sameType(1, 10);
    is.sameType({},[]); // false

簡単に厳密な型チェックができる。

存在チェック


    // 空っぽい
    is.empty({});
    is.empty('');

    // 存在する
    is.existy({});
    is.existy('');

    // trueっぽい
    is.truthy({});
    is.truthy('1');

    // falseっぽい
    is.falsy(0);
    is.falsy('');

    // スペース1文字だけ
    is.space(' ');
    is.space("\t");
    is.space('  '); // 2文字はfalse
    is.space(' '); // 全角はfalse

こちらは比較的アバウトな比較。
is.spaceは"\v"、"\r"、"\n"、"\f"に対してもtrue。"\b"は対象外。

正規表現

    // URLである
    is.url('http://www.example.com');
    is.url('p.m.ls'); // true
    is.url('p.m.l.s'); // false

    // メールアドレスである
    is.email('a.b@c.d');
    is.email('a..b@c.d'); // false

    // 16進数である
    is.hexadecimal('abcdef');

    // CSSカラーコード形式である
    is.hexColor('#ff0000');
    is.hexColor('#f00');
    is.hexColor('red'); // false

    // IPアドレスである
    is.ip('192.168.0.1');
    is.ip('fc00::1');

    // IPv4アドレスである
    is.ipv4('192.168.0.1'); // true
    is.ipv4('fc00::1'); // false

    // IPv6アドレスである
    is.ipv6('192.168.0.1'); // false
    is.ipv6('fc00::1'); // true

    // 英数
    is.alphaNumeric('alphaNu3er1k');
    is.alphaNumeric('a_b'); // false

    // 時刻
    is.timeString('12:34:56')
    is.timeString('1:2:3')
    is.timeString('12:34:60') // false

    // 年月日
    is.dateString('01/01/2017'); // 区切りは/-いずれか
    is.dateString('2017/01/01'); // false

    // 肯定的である
    is.affirmative('yes');
    is.affirmative('no'); // false

    // クレジットカード
    is.creditCard(378282246310005)

    // アメリカの郵便番号
    is.usZipCode('12345-6789'); // true
    is.usZipCode('100-0001'); // false

    // カナダの郵便番号
    is.caPostalCode('L8V3Y1'); // true
    is.caPostalCode('100-0001'); // false

    // イギリスの郵便番号
    is.ukPostCode('B184BJ'); // true
    is.ukPostCode('100-0001'); // false

    // 北米の電話番号
    is.nanpPhone('609-555-0175'); // true

    // アメリカの社会保障番号
    is.socialSecurityNumber('017-90-7890'); // true

    // EPP(Extensible Provisioning Protocol)
    is.eppPhone('+90.2322456789'); // true

わりとざっくり。
日本ではちょっと使えないものが多いというか、ライブラリに入れるようなものなのかこれ。
is.affirmativeは1、't'、'true'、'y'、'yes'、'ok'、'okay'だけがtrueになるようだ。affirmative自身もfalse。

文字列


    // 文字が含まれるか
    is.include('I am a Cat', 'I am'); // true
    is.include('I am a Cat', 'i am'); // false

    // 文字で始まるか
    is.startWith('I am a Cat', 'I am'); // true
    is.startWith('I am a Cat', 'a Cat'); // false

    // 文字で終わるか
    is.endWith('I am a Cat', 'I am'); // false
    is.endWith('I am a Cat', 'a Cat'); // true

    // 単語が大文字開始か
    is.capitalized('I am a Cat') // false
    is.capitalized('I Am A Cat') // true

    // 全て大文字か
    is.upperCase('AAA'); // true
    is.upperCase('AaA'); // false

    // 全て小文字か
    is.lowerCase('aaa'); // true
    is.lowerCase('aAa'); // false

    // 回文か
    is.palindrome('Sator Arepo Tenet Opera Rotas.'); // true [a-zA-Z0-9]以外は全削除される
    is.palindrome('竹藪焼けた'); // true 日本語も削除対象なので正しく動かない

is.palindrome以外は日本語も動作するが、日本語は大文字とかないのでis.upperCase等は常にtrueになる。
になったりはしない。

算術


    // 同じである
    is.equal(40+2, 42); // true
    is.equal(a=new Date(), b=a) // string、number、boolean以外はfalse

    // 偶数である
    is.even(2);

    // 奇数である
    is.odd(1);

    // 0より大きい
    is.positive(1);
    is.positive('1'); // false

    // 0未満である
    is.negative(-1);
    is.negative(0); // false

    // より大きい
    is.above(2, 1); // 第二引数より大きければtrue
    is.above(2, 2); // 同値はfalse

    // より小さい
    is.under(2, 3); // 第二引数より小さければtrue
    is.under(2, 2); // false

    // 値が間にあるか
    is.within(2, 1, 3); // 第二引数より大きく第三引数より小さければtrue
    is.within(2, 2, 2); // false

    // 小数である
    is.decimal(1.1);
    is.decimal(1.0); // false

    // 整数である
    is.integer(1);
    is.integer(1.1); // false
    is.integer(1.0); // true

    // 有限である
    is.finite(1);
    is.finite(Infinity); // false

    // 無限である
    is.infinite(Infinity);
    is.infinite(1); // false

1.01に丸め込まれるようだ。

オブジェクト


    // プロパティ数
    is.propertyCount({a:0,b:0}, 2);

    // プロパティ名が存在するか
    is.propertyDefined({a:'b'}, 'a');
    is.propertyDefined({a:'b'}, 'b'); // false

propertyDefinedproperty_exists()

配列


    // in_array()
    is.inArray(1, [1, 2]);
    is.inArray(1, {a: 1}); // false

    // ソートされているか
    is.sorted([1, 2, 3]); // デフォルト第二引数は`>=`
    is.sorted([1, 3, 2]); // false
    is.sorted([3, 2, 1], '<'); // true

何故inArrayだけ引数が逆順なのか。

環境


    // IEか
    is.ie();
    is.ie(10); // IE10か
    is.ie('>=10'); // IE10以上か

    // Chromeか
    is.chrome();

    // Firefoxか
    is.firefox();

    // Edgeか
    is.edge();

    // Operaか
    is.opera();

    // safariか
    is.safari();

    // phantomjsか
    is.phantom()

    // iosか
    is.ios();

    // iPhoneか
    is.iphone();

    // iPadか
    is.ipad();

    // iPodか
    is.ipod();

    // Androidか
    is.android();

    // Androidスマホか
    is.androidPhone();

    // Androidタブレットか
    is.androidTablet();

    // Blackberryか
    is.blackberry();

    // Windows Phoneか
    is.windowsPhone();

    // Windowsタブレットか
    is.windowsTablet();

    // Windowsか
    is.windows();

    // Mac OS Xか
    is.mac();

    // Linuxか
    is.linux();

    // デスクトップPCか
    is.desktop();

    // 携帯端末か
    is.mobile();

    // タブレットか
    is.tablet();

    // 現在オンラインか
    is.online(); // navigator.onLine

    // 現在オフラインか
    is.offline(); // 何故かCannot read property 'apply' of undefinedになる

    // タッチ可能なデバイスか
    is.touchDevice();

is.ie以外にもis.chromeis.firefoxあたりはバージョン指定で検索可能。

時刻


    var today = new Date();
    var yesterday = new Date(new Date().setDate((today.getDate())-1));
    var tomorrow  = new Date(new Date().setDate((today.getDate())+1));
    var millennium = new Date('2001/01/01 00:00:00');

    // 今日か
    is.today(today);
    is.today(yesterday); // false
    is.today(); // false!

    // 昨日か
    is.yesterday(yesterday); // true
    is.yesterday(today); // false

    // 明日か
    is.tomorrow(tomorrow); // true
    is.tomorrow(today); // false

    // 過去か
    is.past(yesterday); // true
    is.past(today); // false

    // 未来か
    is.future(tomorrow); // true
    is.future(today); // false

    // その曜日か
    is.day(millennium, 'monday'); // 2001/01/01は月曜
    is.day(millennium, 'sunday'); // false

    // その月か
    is.month(millennium, 'january');
    is.month(millennium, 'february'); // false

    // その年か
    is.year(millennium, 2001);
    is.year(millennium, '2001'); // false

    // 閏年か
    is.leapYear(2000); // true
    is.leapYear(new Date('2000/01/01 00:00:00')); // false!

    // 週末か
    is.weekend(new Date('2001/01/06 00:00:00')); // 土日がtrue
    is.weekend(millennium); // false

    // 平日か
    is.weekday(millennium); // true
    is.weekday(new Date('2001/01/06 00:00:00')); // 土日がfalse

    // 日付が間にあるか
    is.inDateRange(today, yesterday, tomorrow); // 第二引数より大きく第三引数より小さければtrue
    is.inDateRange(millennium, yesterday, tomorrow); // false

    // 過去一週間以内か
    is.inLastWeek(yesterday); // '先週'ではない
    is.inLastWeek(today); // false

    // 過去一ヶ月以内か
    is.inLastMonth(yesterday); // '先月'ではない
    is.inLastMonth(new Date(new Date().setMonth((today.getMonth())-1))); // false

    // 過去一年以内か
    is.inLastYear(yesterday); // '昨年'ではない
    is.inLastYear(new Date(new Date().setYear((today.getYear())-1))); // false

    // この先一週間以内か
    is.inNextWeek(tomorrow); // '来週'ではない
    is.inNextWeek(today); // false

    // この先一ヶ月以内か
    is.inNextMonth(tomorrow); // '来月'ではない
    is.inNextMonth(new Date(new Date().setMonth((today.getMonth())+1))); // false

    // この先一年以内か
    is.inNextYear(tomorrow); // '来年'ではない
    is.inNextYear(new Date(new Date().setYear((today.getYear())+1))); // false

    // 指定の四半期か
    is.quarterOfYear(millennium, 1); // true 1月スタート
    is.quarterOfYear(millennium, 2); // false

    // 夏時間か
    is.dayLightSavingTime(new Date('2001/06/01 00:00:00')); // 日本では常にfalse

便利ではあるが、JavaScriptはDateの存在自体が罠なのであまり積極的に使いたいものではない。

設定


    // 正規表現変更
    is.setRegexp(/^\d+$/, 'alphaNumeric'); // is.alphaNumericをA-Za-z0-9から0-9に変更
    is.alphaNumeric('123'); // true
    is.alphaNumeric('abc'); // false

    is.setRegexp(/^[\u3040-\u30ff]+$/, 'zenkaku'); // これは動かない
    is.zenkaku('ほげ'); // JavaScriptエラー

    // 名前変更
    var hoge = is.setNamespace();
    hoge.boolean(false); // isの名前が変わる
    is.boolean(false); // JavaScriptエラー is=undefinedになる

設定変更系の特殊なメソッド。
is.setRegexpは任意の名前をセットできるかと思いきや、既存の正規表現を変更することしかできないというがっかり仕様。

派生メソッド

ここまでに挙げた「設定」以外の全is.**メソッドに対して、is.not.**でnot検索ができる。


    is.not.boolean(1); // true
    is.not.boolean(false); // false

    is.not.within(2, 2, 2); // 範囲内はない

    is.not.ie(); // IE以外である

    is.not.online(); // is.offline()と同じ

    is.not.past(today); // 過去ではない

「環境」「設定」以外の、引数がひとつのメソッドでは、is.any.**で複数渡したパラメータのうち少なくとも一つが対象であるかを、is.all.**で引数全てが対象であるかをチェックできる。

    is.all.number(1, 2, 3); // true
    is.all.number(1, 2, null); // false
    is.any.number(1, 2, null); // true
    is.any.number('1', undefined, null); // false

さすがにis.not.all.numberとかは書けない。
is.inNextYearあたりはヘルプではall、any非対応になっているけど、普通に対応してる。

感想

○○かそうでないかを確かめたい、をとにかく詰め込んだライブラリ。
色々と範囲がばらばらで、一見まとまりがないようにも見えるけど、実際あったら便利なものが多い。
もうnull==undefinedの罠に怯える必要はないぞ。

58
50
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
58
50