「JavaScriptのイディオム集@nmi.jp」をJSXでやるとどうなるの、っと

JavaScript イディオム集JSX でやってみました。jsx --testで実行できます。

総じて見ると、値の変換は「x as string|number|int」でできる分単純になっているほか、全体的に単純になっていて覚えるべきイディオムは少なくなっています。また、~array.indexOf(item)のような高速化のためのイディオムは不要です*1

このあたり、他の AltJS でどうなのかも知りたいですね。

import "test-case.jsx";
import "js.jsx";

class _Test extends TestCase {
  // 数値化
  function testNumify() : void {
    var v = "123";
    this.expect(v as number + 100).toBe(223);
    // Math.parseFloat()もつかえる
  }

  // 文字列化
  function testStringify() : void {
    var v = 123;
    this.expect(v as string + "123").toBe("123123");
  }

  // null / undefined の区別はなし

  // スコープ化
  function testScope() : void {
    // スコープの扱いはJSとおなじ
    // ただしスクリプト全体を覆う必要はない
    (():void -> {
      var localVar = "hello world";
      this.expect(localVar).toBe("hello world");
    }());
    // ここでlocalVarは参照できない
  }

  // &&, ||
  function testLogicalOps() : void {
    var o = { f : ():string -> { return "hello world"; } };
    // C++とおなじで値を返すものにしか使えない。以下は不可
    // o && o["f"] && this.expect(o["f"]()).toBe("hello world");
  }

  // v = v || {}
  function testDefaultValue() : void {
    var v = null : Map.<string>;
    v = v ?: { foo: "bar" }; // v ? v : { ... } の省略形
    this.expect(v["foo"]).toBe("bar");
  }

  // 数値化、かつNaN以外を保証
  function testNumifyButNaN() : void {
    var v = "xxx";
    this.expect(v as number ?: 0).toBe(0);
  }

  // 整数化
  function testIntify() : void {
    var v = "123.4";
    this.expect(v as int).toBe(123);
    // Math.floor()でもよい
    // ただしint型の演算はnumberとくらべて遅くなるので注意
  }

  // 論理化
  function testBoolify() : void {
    var v = 1;
    this.expect(v as boolean).toBe(true);
  }

  // NaNチェック
  function testNaNCheck() : void {
    var v = NaN;
    // 組み込み関数はコンパイラによる最適化の対象になるので
    // 積極的に使って良い
    this.expect(Number.isNaN(v)).toBe(true);
  }

  // Array#indexOf()
  function testIndexOf() : void {
    var a = [10, 20, 30];
    // 組み込み関数はコンパイラによる最適化の対象になるので
    // 積極的に使って良い(今は特別な変換は行われない)
    this.expect(a.indexOf(10) != -1).toBe(true);
    this.expect(a.indexOf(40) != -1).toBe(false);
  }

  // global object
  function testGlobal() : void {
    this.expect(js.global).notToBe(null);
  }

  // strict modeは存在しない

  // 定義されているかどうか
  function testDefined() : void {
    // 未定義のシンボルはコンパイルエラーになる

    // native classは js.globalを通じてチェック可能
    this.expect(js.global["NativeFoo"] != null).toBe(false);
  }

  // 符号なし整数化
  function testUnsignedIntify() : void {
    var n = 0x80000000;
    this.expect((n|1))      .toBe(-2147483647);
    this.expect((n|1) >>> 0).toBe( 2147483649);
  }
}
// vim: set tabstop=2 shiftwidth=2 expandtab:

*1:現段階で未対応なものも、要望次第で実装しますので。