正确扩展ES6中的阵列/代理?

时间:2017-09-17 21:28:03

标签: javascript arrays node.js ecmascript-6

目前正在尝试制作一个Array / Object的自定义实现(我认为最终会非常相似)并且偶然发现一个让我发疯的问题。

正如你所看到的,b只是一个instanceOf数组,即使它是从自定义类CachedArray创建的,因此我的自定义函数testPush没有被定义,我不能为了一切找到问题所在。

使用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




1 个答案:

答案 0 :(得分:2)

  

是否有替代我想要实现的目标?基本上我需要一个带有我的一些额外功能的数组,但是有一个代理连接到它,这样我就可以进一步处理发生在我的类实例上的任何写操作(所以,数组)

好吧,代理有一个处理程序,允许您挂钩与代理对象的每种交互。因此,您应该使用它来注入要添加到代理对象的任何其他方法。例如,只需提供get,以便它返回自定义函数,而不是将回调中继回目标:

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);
}