Node.js

Node.js Advent Calendar が埋まってなかったので、代わりに細かすぎて伝わりにくいTips入れていきます。

util.format

あんまり単体では使ってないかもしれませんが、所謂%s%d といった formatter を渡して文字列を出力する、 printf のような振る舞いをする関数です。

const util = require('util')
const foo = 'Hello World'

const str = util.format('Test String %s', foo) // Test String Hello World

「単体では」と銘打ったのは理由があって、 console.logconsole.warn といった console のメソッドが内部的に利用しているのがこの util.format だからです。 Template String Literal ができて文字列埋め込みが簡単になったとはいえ、僕個人的にはまだ console で表記するのにこの %d%s を使うことが多いです。

おさらい:

  • %s - 文字列
  • %d - 浮動小数もしくは整数の数字
  • %i - 整数
  • %f - 浮動小数
  • %j - JSON, もしも再帰の値を含む場合は例外を投げるわけじゃなく、 [Circular] として表示する。

本題の %o

で、 %o ですが、これは object を文字列化するのに使います。 %j は内部的に JSON.stringify できるかを試した後に再帰が含まれている例外だったら [Circular] にしますが、 %o の場合は objectproperty を一つ一つ表示します。

ちなみに v8.4.0 からの新機能です。

object の中身をちらっと確認するのにわざわざ console.log(JSON.stringify(obj)) してるのであれば %o のフォーマッターを覚えたほうが良いです。

const obj = {
  foo: 'bar'
}

console.log(`Hello ${obj}`) // Hello [object Object]
console.log(`Hello ${JSON.stringify(obj)}`) // Hello {"foo":"bar"}
console.log('Hello %j', obj) // Hello {"foo":"bar"}
console.log('Hello %o', obj) // Hello { foo: 'bar' }

const circularObj = {
  foo: 'bar',
}
circularObj.bar = circularObj

console.log(`Hello ${circularObj}`) // Hello [object Object]
console.log(`Hello ${JSON.stringify(circularObj)}`) // 例外が投げられる
console.log('Hello %j', circularObj) // Hello [Circular]
console.log('Hello %o', circularObj) // Hello { foo: 'bar', bar: [Circular] }

// 適当に表示するだけなら %o でイナフ
console.log('Hello %o', 'aaaa') // Hello 'aaaa'
console.log('Hello %o', 122) // Hello 122
console.log('Hello %o', Symbol('aaa')) // Hello Symbol(aaa)

// Enumerableじゃないものは表示したくなければ %O を覚えると良い。

console.log('Hello %o', [1,2,3]) // Hello [ 1, 2, 3, [length]: 3 ]
console.log('Hello %O', [1,2,3]) // Hello [ 1, 2, 3 ]

でまぁ、中身的には util.inspect を実行しています。余談ですが、 util.inspect も便利です。

util.inspect API

%o はかなり雑に表示できるので、一番使い勝手が良いです。 %j は今後はあまり使われないものになると思います。