Вы не можете сделать это, не вставая между объектом и тем, что его вызывает, или изменяя объект.Не существует никакого «прикосновения к этому взаимодействию», которое не затрагивает ни то, ни другое.
Вот каждый из них:
Как добраться между ними
Если вы можете получить междуобъект и вызывающая его вещь, вы можете создать для этого новый объект с функциями, дублирующими функции целевого объекта, который его вызывает.Вот простой пример:
const original = {
value: 42,
doSomething() {
console.log(`original doSomething: this.value is ${this.value}`);
},
doSomethingElse() {
console.log(`original doSomethingElse: this.value is ${this.value}`);
}
};
const insertion = {};
for (const key of Object.keys(original)) {
const func = original[key];
if (typeof func === "function") {
insertion[key] = function(...args) {
console.log("insertion " + key + " [before]");
const thisArg = this === insertion ? original : this;
const result = Reflect.apply(func, thisArg, args);
console.log("insertion " + key + " [after]");
return result;
};
}
}
// Here's the code calling the object's methods;
// note we've gotten in the way by giving the code
// `insertion` rather than `original`:
insertion.doSomething();
insertion.doSomethingElse();
Вы также можете сделать это с помощью Proxy
, хотя это более сложно и усложнение ничего не дает в этом случае.
Обратите внимание, что по очевидным причинам он будет перехватывать только вызовы, сделанные через insertion
.Это означает, что если doSomething
вызывает doSomethingElse
, в приведенном выше случае вы перехватите вызов doSomething
, но не вызов doSomethingElse
.
Изменение объекта
Вы можетесделайте это, заменив методы объекта следующим образом:
const original = {
value: 42,
doSomething() {
console.log(`original doSomething: this.value is ${this.value}`);
},
doSomethingElse() {
console.log(`original doSomethingElse: this.value is ${this.value}`);
}
};
for (const key of Object.keys(original)) {
const func = original[key];
if (typeof func === "function") {
original[key] = function(...args) {
console.log(key + " [before]");
const result = Reflect.apply(func, this, args);
console.log(key + " [after]");
return result;
};
}
}
// Here's the code calling the object's methods
original.doSomething();
original.doSomethingElse();
Поскольку это изменяет сам объект, вы увидите все вызовы.