Собираем ключ-значение, выдёргиваем значения:
[...new Map(arr.map(n => [ n.value, n ])).values()]
// или
Object.values(arr.reduce((acc, n) => (acc[n.value] ??= n, acc), {}))
Фильтрация, запоминаем кого встретили, первый раз пропускаем, остальные нет:
arr.filter(function(n) {
return !(this[n.value] = this.hasOwnProperty(n.value));
}.bind({}))
// или
arr.filter(function({ value }) {
return !this.set(value, this.has(value)).get(value);
}, new Map)
// или
arr.filter(((picked, { value: n }) => !picked.has(n) && picked.add(n)).bind(null, new Set))
Фильтрация, ищем элемент похожий на текущий, его же и нашли - окей:
arr.filter((n, i, a) => n === a.find(m => m.value === n.value))
// или
arr.filter((n, i, a) => i === a.findIndex(m => Object.is(m.value, n.value)))
Ну и чего-нибудь странного ещё добавим:
Array.from(
new Set(arr.map(n => n.value)),
n => arr.find(m => m.value === n)
)
// или
arr
.slice()
.sort((a, b) => a.value.localeCompare(b.value))
.filter((n, i, a) => n.value !== a[i - 1]?.value)