JavaScriptの型変換に今更刺し殺される

ある日デバッガを見ていたらこんな文字列が目に入った

Mon Feb 13 2017 18:55:53 GMT+0900 (JST)1000

ナニコレ…?

ソース見たらこんな風になっていた

var now = new Date();
var startTime = now - 1000;
var endTime = now + 1000;

Dateオブジェクトに数値を足し引きしようとしている?!

ていうか、このコード、よく今まで問題なく動いてたなwww

> new Date() + 1000
'Mon Feb 13 2017 19:02:18 GMT+0900 (JST)1000'
> new Date() - 1000
1486980143743

Dateに引き算すると数値型に変換されてエポックになる。これは意図通りだが、足し算すると文字列型に変換されるわけですか、足そうとしているのが数値でもか。であれば

> +new Date() + 1000
1486980570179

ついでなので他のオブジェクトも見てみますかw

> [] + 1000
'1000'
> [] - 1000
-1000
> [1,2,3] + 1000
'1,2,31000'
> [1,2,3] - 1000
NaN

空の配列を数値に型変換すると 0 、文字列に型変換すると空文字列。空でない配列を数値に型変換するとNaNになるあたり勘弁してほしい。

> {} + 1000
1000
> {} - 1000
-1000

ん?

> new Object() - 1000
NaN
> new Object() + 1000
'[object Object]1000'

んん?

もしかして {} はオブジェクトではなくブロックとして扱われているのか? ならば

> ({}) - 1000
NaN
> ({}) + 1000
'[object Object]1000'

もうやだこれwww

> Object.create({}, {toString: {value: function(){ return 'くそ' }}}) + 1000
'くそ1000'

こういう挙動を個別に覚えなくてもいいようなコーディングを心がけたいところ。だーけーど、それならば静的型付け言語の方がいいのでは…、という話になっちゃうんすよね。