Node.js Advent Calendar が埋まってなかったので、代わりに細かすぎて伝わりにくいTips入れていきます。
util.isObject は既に deprecated
util
パッケージには isObject
、 isFunction
といった引数に渡した値が何なのかをチェックする便利関数がありますが、既に Node v4 から deprecated
です。
deprecated になっている util.isXXX 系一覧
- util.isObject
- util.isFunction
- util.isArray
- util.isBuffer
- util.isDate
- util.isNull
- util.isNullOrUndefined
- util.isError
- util.isNumber
- util.isPrimitive
- util.isRegExp
- util.isString
- util.isSymbol
- util.isUndefined
代替手段
基本的には typeof
もしくは instanceof
を使って下さい。
Array
と Buffer
に関しては Array.isArray
と Buffer.isBuffer
を使って下さい。 isPrimitive
とかの複合的なものに関しては代替は無いです。 typeof
を組み合わせて自分で作って下さい。
Deprecated になった経緯
今は昔、 io.js 時代に起きたことです。
util.isObjectがわかりにくいのではないか?という issue が立ち上がります。経緯となったのは下記のコードです。
var f = function(){}
util.isObject(f) // false
ここで議論になったのは「関数は object なのかどうか」です。
Node.js の過去の実装では util.isObject
はこうなってます。
arg !== null && typeof arg === 'object'
function
は typeof
では object
にならないので、このままでは false
です。
どっちが正しいのでしょうか?結論から言うと、 ECMAScriptの仕様 に書いてあります。
ECMAScript の Type は、 undefined
, null
, string
, symbol
, number
, boolean
, object
のみ掲載されています。つまり、 **『function
は object
の1つという解釈が一般的』 **です。
これらの解釈を受けてunderscore
や lodash
の実装は下記のとおりで、関数でも isObject
は true
になります。
function isObject(value) {
const type = typeof value
return value != null && (type == 'object' || type == 'function')
}
で、これは確かに問題である、 util.isObject
を直したほうが良さそうだ、という事になりました。
しかし、 util.isObject
という関数は既にリリースされており、動きを変えてしまうと影響を受けるライブラリも多いだろうということで折衷案として動きを変えずに deprecated
で手を打とうという事になりました。
Node.js のような広く使われているライブラリの場合はこういう動き1つ変えるのにも大変です。 この手の話が多いため、 Node.js に新しい utility を付けたいという意見も多いのですが、一時期は本当に慎重でした。 npm で解決できるようなものに関しては npm にまかせてコアに追加するものに関しては本当に必要なものだけにしようという話も多かったです。この考え方を Less is More
と言います。
ちなみに最近追加されたutilityで言うと、 util.isDeepStrictEqual
ですが、よく追加されたなぁと思いました。