このコードを実行したときの出力(プロパティ順)はどうなるでしょうか?

const obj = { foo: 1, bar: 2, baz: 3 }
const obj2 = { ...obj, bar: 4 }
console.log(JSON.stringify(obj2, null, " "))

答えはこうなります

{
"foo": 1,
"bar": 4,
"baz": 3
}

bar は最後に来ず obj を展開したときの最初の場所です

const obj2 = {}
obj2.foo = 1
obj2.bar = 2
obj2.baz = 3
obj2.bar = 4

と書いた場合と同じです

この仕組み 順番に意味を持たせたいときに良くも悪くもあるんですよね
この場合は bar は常に上書きするもので obj.bar はいらないものです
なのにそれのせいで順番が決まってしまいます

オブジェクトで順番は無いものと考えるべきという主張もありますが 必要になるときもあるものです

上書きするものを除外したオブジェクトを作ればできなくはないものの面倒がありますし 数が多いと書くのが面倒です

const obj = { foo: 1, bar: 2, baz: 3 }
const { bar, ...rest } = obj
const obj2 = { ...rest, bar: 4 }
console.log(JSON.stringify(obj2, null, " "))
{
"foo": 1,
"baz": 3,
"bar": 4
}

関数を用意しておけば書く場所は楽になりますが こんなことしないといけないのかって気持ちになります

const merge = (...objs) => {
const result = {}
for (const obj of objs) {
for (const [k, v] of Object.entries(obj)) {
if (result.hasOwnProperty(k)) {
delete result[k]
}
result[k] = v
}
}
return result
}

const obj = { foo: 1, bar: 2, baz: 3 }
const obj2 = merge(obj, { bar: 4 })
console.log(JSON.stringify(obj2, null, " "))
{
"foo": 1,
"baz": 3,
"bar": 4
}

ただ 今の動きで助かってる部分もあるのでデフォルト挙動が変わってほしいかというと難しいところです
localStorage などに JSON 文字列を保存して それと現状に差分があるかを確認したいときなんかは今のほうが嬉しいです
JSON 文字列比較だとプロパティ順の違いで不一致になるので順番が変わってほしくないです
イミュータブルオブジェクトとして扱いたいときは上に書いたような方法で obj2 を作るのでこれで毎回順番が変わるとチェックが面倒になります