The "problem" is not with the proxy - all calls already go through it. The issue is the age old specifics of how the this keyword works. In short, it's determined at call time, so this.object will have a different meaning depending on when and how the function is called. In this case, the value of this is "lost" not unlike how you lose it in a callback.
If you need to refer to something concretely, you have a few choices
Lexically bind this using an arrow function () => {}
An arrow function uses the this value of the enclosing context at creation time, so it doesn't vary at call time:
class Hook {
    constructor(object) {
        this.object = object;
    }
    toStringProperty() {
        const handler = {
            apply: (target, thisArg, args) => { //<--- arrow function
                if (thisArg === Function.prototype.toString) {
                    return 'function toString() { [native code] }'
                }
                if (thisArg === this.object) {
                    return "Hooked String"
                }
                return target.apply(thisArg, args)
            }
        }
        Function.prototype.toString = new Proxy(Function.prototype.toString, handler)
    }
}
let hook = new Hook(HTMLAudioElement);
hook.toStringProperty();
// Interesting enough this when called (I use Devtools) logs Proxy Object itself but only happen if I use a Class
console.log(Function.prototype.toString)
console.log(HTMLAudioElement.toString())
 
 
This is basically redundant with arrow functions, but still an option:
class Hook {
    constructor(object) {
        this.object = object;
    }
    toStringProperty() {
        const handler = {
            apply: function (target, thisArg, args){
                if (thisArg === Function.prototype.toString) {
                    return 'function toString() { [native code] }'
                }
                if (thisArg === this.object) {
                    return "Hooked String"
                }
                return target.apply(thisArg, args)
            }.bind(this) //<--- bind `this` from creation time
        }
        Function.prototype.toString = new Proxy(Function.prototype.toString, handler)
    }
}
let hook = new Hook(HTMLAudioElement);
hook.toStringProperty();
// Interesting enough this when called (I use Devtools) logs Proxy Object itself but only happen if I use a Class
console.log(Function.prototype.toString)
console.log(HTMLAudioElement.toString())
 
 
Capture the value in a variable
This avoids the usage of this by capturing the value of this.object at creation time with const obj = this.object and just using obj later which will always have the same value:
class Hook {
    constructor(object) {
        this.object = object;
    }
    toStringProperty() {
        const obj = this.object; //<--- capture 
        const handler = {
            apply: function (target, thisArg, args){
                if (thisArg === Function.prototype.toString) {
                    return 'function toString() { [native code] }'
                }
                if (thisArg === obj) { //<--- use
                    return "Hooked String"
                }
                return target.apply(thisArg, args)
            }
        }
        Function.prototype.toString = new Proxy(Function.prototype.toString, handler)
    }
}
let hook = new Hook(HTMLAudioElement);
hook.toStringProperty();
// Interesting enough this when called (I use Devtools) logs Proxy Object itself but only happen if I use a Class
console.log(Function.prototype.toString)
console.log(HTMLAudioElement.toString())