0

I want to add a side effect every when an array being pushed. For example, I want to add console.log:

var arr = [];
arr.push(1); // => I want it to work normally, and in addition, it logs 1 to the console

How to achieve that? I'm looking for a solution using Proxy and I have tried handler.get() and handler.apply() but still, can't figure it out.

5
  • 1
    you could hijack the Array prototype push function to do this, but I don't know why you can't just create another function that takes an array as a parameter, does something and then pushes to the array. Commented Jan 25, 2021 at 16:18
  • @wootscootinboogie Imagine I'm adding console.log just for the debugging purpose, and it's on an existing codebase, I want to modify the existing code base as little as possible. Let me try prototype. Commented Jan 25, 2021 at 16:20
  • @DBS - yes it appears so. Thanks for pointing it out. Commented Jan 25, 2021 at 16:25
  • @wootscootinboogie From what you've suggested I can solve the problem now, do you want to write an answer? Commented Jan 25, 2021 at 16:28
  • 1
    Overriding base prototypes can be dangerous, everything on window including third-party code will use this. Strongly suggest creating a custom func. Commented Jan 25, 2021 at 17:00

2 Answers 2

3

To directly answer your initial question...you need to return a closure from the get trap. To actually trap this, you would need to use proxy.push() instead of array.push(), though. For example:

const arr = [];

const arrProxy = new Proxy(arr, {
  get(target, prop) {
    if (prop === 'push') {
      return (...args) => {
        console.log(...args);
        return target[prop](...args);
      };
    }
    return target[prop];
  }
});

arrProxy.push('test');
arrProxy.push('test1', 'test2');

Sign up to request clarification or add additional context in comments.

2 Comments

What if what I want is console.log('test'), not console.log(1)
Well, array.push() can be provided more than one parameter. What would you like to happen if there's more than one value? If we assume there's only ever one parameter, you can just replace 1 with args[0] but I wouldn't recommend it. You most likely want to do console.log(args); (Updated answer)
1

Here's the final answer that I'm comfortable with, it doesn't use Proxy by the way.

{

var arr = [];

// add push
arr.push = function (...items) {
  console.log(...items);
  Array.prototype.push.apply(this, items);
};

arr.push('test');
arr.push('test1');

// clean up the push
delete arr.push;

}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.