Implement a Logging Proxy in JavaScript
The Proxy pattern is a structural design pattern that provides a surrogate or placeholder for another object to control access to it. This challenge will focus on implementing a logging proxy that intercepts method calls to an underlying object and logs information about each call. This is useful for auditing, debugging, or adding cross-cutting concerns without modifying the original object.
Problem Description
Your task is to create a JavaScript LoggingProxy that wraps an existing object. This proxy should intercept all method calls made to the wrapped object. For each intercepted method call, the proxy must:
- Log the name of the method being called.
- Log any arguments passed to the method.
- Execute the original method on the wrapped object.
- Log the return value of the method.
- Return the original method's return value.
You should use JavaScript's built-in Proxy object for this implementation.
Key Requirements:
- The proxy must handle any method that can be called on the target object.
- The logging should clearly indicate the method name, its arguments, and its return value.
- The original functionality of the target object must be preserved.
Expected Behavior:
When a method is called on the proxy, you should see log messages in the console detailing the operation. The proxy should behave exactly like the original object in terms of functionality.
Edge Cases to Consider:
- Methods with no arguments.
- Methods that return
undefined. - Methods that throw errors (though for this challenge, we'll assume successful execution for logging purposes; error handling can be a future extension).
Examples
Example 1:
const calculator = {
add: function(a, b) {
return a + b;
},
subtract: function(a, b) {
return a - b;
}
};
const loggingCalculator = new LoggingProxy(calculator);
console.log(loggingCalculator.add(5, 3));
// Expected Console Output:
// Calling method: add
// Arguments: [5, 3]
// Returning: 8
// 8
console.log(loggingCalculator.subtract(10, 4));
// Expected Console Output:
// Calling method: subtract
// Arguments: [10, 4]
// Returning: 6
// 6
Explanation:
The LoggingProxy intercepts calls to add and subtract. It logs the method name and arguments, then executes the original method, logs the return value, and finally returns the result.
Example 2:
const greeter = {
greet: function(name) {
return `Hello, ${name}!`;
},
farewell: function() {
return "Goodbye!";
}
};
const loggingGreeter = new LoggingProxy(greeter);
console.log(loggingGreeter.greet("Alice"));
// Expected Console Output:
// Calling method: greet
// Arguments: ["Alice"]
// Returning: Hello, Alice!
// Hello, Alice!
console.log(loggingGreeter.farewell());
// Expected Console Output:
// Calling method: farewell
// Arguments: []
// Returning: Goodbye!
// Goodbye!
Explanation:
This example shows the proxy handling methods with and without arguments, demonstrating its flexibility.
Constraints
- The proxy must be implemented using
new Proxy(target, handler). - The
handlerobject should use thegettrap to intercept method calls. - All logging should be done using
console.log(). - The target object can have any number of methods.
Notes
- Consider how to access and invoke the original methods on the
targetobject within thegettrap. - Remember that
Proxyintercepts property access, not just method calls directly. You'll need to check if the accessed property is a function before attempting to call it. - The
handler.gettrap receivestarget,property, andreceiveras arguments. Thepropertyargument will be the name of the method being accessed.