2

Currently trying to make a custom implementation of Array / Object (Would end up being pretty similar i suppose) and have stumbled upon an issue that is driving me crazy.

As you can see, b is only an instanceOf Array, even though its created from custom class CachedArray, thus my custom function testPush is not defined, and i cant for the sake of everything find what is the issue.

Using Nodejs 6

function _setKey(target, key, value) {
  console.log('Setting value', key, 'to', value);
  target[key] = value;
  return true;
}

class ExtendableProxy {
  constructor(a, b) {
    return new Proxy(a, b);
  }
}

class CachedArray extends ExtendableProxy {
  constructor(redis, options) {
    let RawArray = [];

    super(RawArray, {
      set: _setKey
    });

    this._rawArray = RawArray;

    this.redis = redis;
    this.options = options;
  }

  testPush() {
    this.push('Its me');
  }
}

var b = new CachedArray();

console.log('b instanceof CachedArray', b instanceof CachedArray); //false
console.log('b instanceof ExtendableProxy', b instanceof ExtendableProxy); //false
console.log('b instanceof Proxy', b instanceof Proxy); //false
console.log('b instanceof Array', b instanceof Array); //true

b.push('Hello.'); //Works just fine, _setKey is called and executed correctly
b.testPush(); //TypeError: b.testPush is not a function

4
  • 1
    That is not how proxies are supposed to be created. Proxies are wrappers around objects, but not types. You are attempting to define a type that extends your base object (in your case Array), but proxies do not work by extending the prototype, so there is no inheritance chain. Commented Sep 17, 2017 at 21:33
  • Possible duplicate of Can I extend Proxy with an ES2015 class? Commented Sep 17, 2017 at 21:40
  • I see, would explain why i couldnt just extend Proxy in the first place. Is there an alternative to what i am trying to achieve? Essentially i need an array with some extra functions of mine, which however has a Proxy connected to it, so that i can further process any writes happening to the instance of my class (So, the Array) Commented Sep 17, 2017 at 21:40
  • Just for reference, here was an attempt of mine at messing around with extending arrays using proxy functionality you can check out here. Commented Sep 17, 2017 at 23:01

1 Answer 1

4

Is there an alternative to what i am trying to achieve? Essentially i need an array with some extra functions of mine, which however has a Proxy connected to it, so that i can further process any writes happening to the instance of my class (So, the Array)

Well, the proxy has a handler that allows you to hook into every kind of interaction with the proxied object. So you should use that to inject any additional methods you want to add to the proxied object. For example, just provide the get so it returns a custom function instead of relaying the call back to the target:

function createCachedArray(arr) {
    const customFunctions = {
        testPush() {
            this.push('It’s me');
        },
    };

    return new Proxy(arr, {
        set (target, property, value) {
            console.log(`Setting value ${property} to ${value}`);
            target[property] = value;
            return true;
        },
        has (target, property) {
            return property in customFunctions || property in target;
        },
        get (target, property) {
            if (typeof property === 'string' && property in customFunctions) {
                return customFunctions[property].bind(target);
            }
            else {
                return target[property];
            }
        },
    });
}

let a = [1, 2, 3];
let b = createCachedArray(a);

b.push('foo');
b.testPush();
for (const x of b) {
    console.log(x);
}
Sign up to request clarification or add additional context in comments.

3 Comments

This is genious! Although i made a small change to it: Within the customFunction i do my calls onto the created proxy instance itself, so that those calls would also get intercepted by the setter callback. I am aware this could cause infinite recursion, but i can live with that / will make sure it doesnt happen. Thanks a lot!
What is the benefit or what are you trying to solve? I am missing you gaining by using proxies?
@jamesemanon Is that a general question what proxies are for? Or are you asking about this particular example? Obviously, this is just a constructed example to show the concept.

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.