@ledsun blog

無味の味は佳境に入らざればすなわち知れず

JS.falsy?

ruby.wasmように値がJavaScriptのFalsyな値か判定する関数を実装しました。

https://github.com/ledsun/ruby.wasm/blob/19b8f245af9806ceb67601f851300d2df6ac5674/packages/gems/js/lib/js.rb#L98-L109

def self.falsy?(value)
  value == JS::Null || value == JS::Undefined ||
    # Use the strictly_eql? method to compare values using JavaScript's `===` operator.
    # This is because JavaScript's `==` operator is loose in its judgment.
    # For example, in JavaScript, `[] == ""` is true, but `[] === ""` is false.
    value.strictly_eql?(JS::EmptyString) || value.strictly_eql?(JS::False) ||
    value.strictly_eql?(JS::Zero) || value.strictly_eql?(JS::NinusZero) ||
    value.strictly_eql?(JS::BingIntZero) ||
    # `Number.isNaN`` is used to compare whether a value is `NaN`` or not.
    # This is because `NaN == NaN` is false in JavaScript, but `Number.isNaN(NaN)` is true.
    JS.global[:Number].isNaN?(value)
end

もっとシンプルになるかと思ってました。 思ったより複雑でした。

というのは、たとえば次の比較は真になります。

JS.eval('return []') == JS.eval("return ''")

なぜかというとJavaScript==がなかなかマイルドだからです。

> []==''
true
> !([])
false
> !('')
true
> []===''
false

そういえば、昔「JavaScript: The Good Parts」を読んだときにこの説明がありました。

その教えを守り、JavaScriptでプログラム書くときは===しか使いません。 それもESLintでAuto Fixしています。 そして、今ではこの仕様のことをすっかり忘れていました。

実装してから気がついたのですが、これは僕が欲しいものでは無かったです。 名前も悪くないし、実装自体は、なかなか気にいっています。 ただ、使い所が思いつかないので、プルリクエストにするのは、一旦やめておきます

いつか使い所を思いついたときのために、自分のリポジトリのブランチとしては残しておきます。