freeze 済みオブジェクトの Proxy が本来と異なる値を返せない
freeze したオブジェクトの Proxy を作る
get でそのままプロパティを返すだけだと特に問題ない

const frozen = Object.freeze({x: 1})

const proxy = new Proxy(frozen, {
get(target, name) {
return target[name]
}
})

console.log(proxy.x)
// 1

同じ値を返せばリテラルでも

const frozen = Object.freeze({x: 1})

const proxy = new Proxy(frozen, {
get(target, name) {
return 1
}
})

console.log(proxy.x)
// 1

異なる値を返そうとすると

const frozen = Object.freeze({x: 1})

const proxy = new Proxy(frozen, {
get(target, name) {
return 2
}
})

console.log(proxy.x)
// Uncaught TypeError: 'get' on proxy: property 'x' is a read-only and non-configurable data property on the proxy target but the proxy did not return its actual value (expected '1' but got '2')
// at <anonymous>:9:19

Proxy 済みの別オブジェクトなのに元の freeze を引き継がせようとしてるみたい
そんな機能いらないけど
でも Proxy にわたすオブジェクトをダミーにすればいいので回避は簡単

本来の取得値に 1 足したものを返したい場合

const frozen = Object.freeze({x: 1})

const proxy = new Proxy(frozen, {
get(target, name) {
return target[name] + 1
}
})

とする代わりに

const frozen = Object.freeze({x: 1})

const proxy = new Proxy({}, {
get(target, name) {
return frozen[name] + 1
}
})

console.log(proxy.x)
// 2

とすればエラーにはならない
メソッドをstatic 関数化
const handler = (ctx, name) => (...args) => ctx.prototype[name].call(...args)
const S = ctor => new Proxy(ctor, { get: handler })

使用例

S(Array).reverse([1, 2, 3])
// [3, 2, 1]

S(String).slice("foobar", 2, 4)
// ob

パイプライン演算子が来たりでもないと基本はメソッドで良さそう
数少ない役立つところは map などの関数に入れる使い方

const SString = S(String)
const texts = [" a ", " b"].map(SString.trim)
// ["a", "b"]

毎回 「x => x.trim()」 って書くの疲れるし
文字数的にはそんなにだけど記号打つのが面倒

この方法だと prototype のメソッドを call するのと一緒なのでキャストされる
配列風なものを配列として扱いたいとかでは使えるけど 変換いらずにただその名前のメソッドを呼び出せればいいならこれで十分そう

const handler = (ctx, name) => (value, ...args) => value[name](...args)
const X = new Proxy({}, { get: handler })

const texts = [" a ", " b"].map(X.trim)
// ["a", "b"]

X.trim が引数の trim を呼び出す関数になるなら
parseInt(X, 2) で X のところに引数が入って呼び出される関数にもなってほしい
parseInt そのままではただの関数呼び出しに X が渡されるだけなので一工夫する

const handler = (ctx, name) => (value, ...args) => value[name](...args)
const fn = f => (...args) => a => f(...args.map(x => x === X ? a : x))
const X = new Proxy(fn, { get: handler })

X に関数を渡して その返り値を関数として使う

const hex2dec = X(parseInt)(X, 16)
hex2dec("ff")
// 255

const bit = X(Math.pow)(2, X)
bit(16)
// 65536

見やすさはなんかいまいち
やっぱり構文として対応してほしい
けど PHP では提案があったけど複雑すぎるとかで却下された話を聞いたし JavaScript でも入らなそうな気はする

少し長くなるけどアロー関数でできるといえばできるし 関数本体部分でちゃんと呼び出し形式になっていてどう実行されるかがわかりやすいし

X => parseInt(X, 2)
X => X.trim()
Object.prototype.__proto__
Object.prototype.__proto__ 変更しようとしたらエラー出るようになってる

Object.prototype.__proto__ = {}

VM225:1 Uncaught TypeError: Immutable prototype object '#<Object>' cannot have their prototype set

昔全体の Proxy 作ろうとして Object.prototype.__proto__ に Proxy オブジェクト入れた気がするけど 変わったのかな
まともに動かずデバッガクラッシュしてたからエラーにしてしまうのはいいけど 全体の Proxy 機能使いたいんだけどなー