使用具有普通数组的代理

时间:2016-04-22 06:04:38

标签: javascript ecmascript-6 es6-proxy

考虑以下代码:

app.mediaLibrary = new function MediaLibrary() {
    var self = this;

    self.media = new Proxy([], {
        set(target, key, value) {
            console.log(`Setting value ${key} as ${value}`)
            if (!(value instanceof self.Media))
                throw new Error(`${value} is not instance of Media.`)
            target[key] = value;
            return true
        },
        get (target, key) {
            console.log(`Getting value ${key} as ${target[key]}`)
            return target[key]
        }
    });

    self.Media = function Media(file, fileReader) {
        this.src = fileReader.result;
        this.file = file;
    }

    return self;
}

每当我致电app.mediaLibrary.media.push(new app.mediaLibrary.Media("", ""))时 在控制台中我看到了:

Getting value push as function push() { [native code] }
Getting value length as 0
Setting value 0 as [object Object]
Setting value length as 1
Uncaught Error: 1 is not instance of Media.(…)

我理解为什么我会看到这个,但我怎么能围绕它编码?我的陷阱似乎是由内部(pushlength)以及外部调用([0]=...)触发的,我不知道如何区分它们。有什么想法吗?

1 个答案:

答案 0 :(得分:1)

我认为你问的是错误的问题。这不是关于内部调用和外部调用,这是关于您代理的特定对象:数组。

你可以选择三个条件:

  1. 长度可以设置为任何东西(只有数组才会处理这个)
  2. 数字属性只能设置为媒体实例。
  3. 所有其他属性都不受限制。
  4. 你可以这样写:

    app.mediaLibrary = new function MediaLibrary() {
        var self = this;
    
        self.media = new Proxy([], {
            set(target, key, value) {
                console.log(`Setting value ${key} as ${value}`)
    
                // Check if this is a valid array index
                // See http://www.ecma-international.org/ecma-262/6.0/#sec-array-exotic-objects
                if (String(key >>> 0) === key && (key >>> 0) != Math.pow(2, 32) - 1) {
                    if (!(value instanceof self.Media))
                        throw new Error(`${value} is not instance of Media.`);
                } else if(key !== 'length') {
                    throw new Error(`${key} may not be written to.`);
                }
                target[key] = value;
                return true
            },
            get (target, key) {
                console.log(`Getting value ${key} as ${target[key]}`)
                return target[key]
            }
        });
    
        self.Media = function Media(file, fileReader) {
            this.src = fileReader.result;
            this.file = file;
        }
    
        return self;
    }
    

    如果你真的需要区分.push[0]=...,那么不,它就无法完成。