我正在寻找类似此示例的内容,使用用户定义的回调/钩子拦截对字符串,数组和对象变量的访问:

var foo = [];
tie( // hypothetical
    foo,
    {
        STORE: // callback triggered when assigning: foo[index] = value
        function(self, index, value) {
            if (value.match('fnord')) {
                self[index] = "Nothing to see here. Move along.";
                return;
            }
            self[index] = value;
        },
        FETCH: // callback triggered when accessing: foo[index]
        function(self, index) {
            if (42 == index) {
                return "This is The Answer.";
            }
            return self[index];
        }
    }
);




该概念的有效实现的简单演示:

package Quux;
use Tie::Array ();
use base 'Tie::StdArray';
sub FETCH {
    my ($self, $index) = @_;
    return 'This is The Answer.' if 42 == $index;
    return $self->[$index];
}
sub STORE {
    my ($self, $index, $value) = @_;
    if ($value =~ 'fnord') {
        $self->[$index] = 'Nothing to see here. Move along.';
        return;
    }
    $self->[$index] = $value;
}

package main;
tie my @foo, 'Quux';
@foo = (undef) x 50;
print $foo[42];
$foo[0] = 'fnord';
print $foo[0];


完整文档:tie(概念),tie()(功能),Tie::Arraymagic

最佳答案

与此功能大致等效的是the Proxy API。这是ES6功能,但是V8已经为其提供了“实验”支持(使用--harmony--harmony-proxies启动节点以启用此功能)。这是用代理重写的代码段:

var foo = (function() {

    var obj = {};
    return Proxy.create({
        set: function(self, index, value) {
            if (value.match(/fnord/)) {
                obj[index] = "Nothing to see here. Move along.";
                return;
            }
            obj[index] = value;
        },
        get: function(self, index) {
            if (42 == index) {
                return "This is The Answer.";
            }
            return obj[index];
        }
    });

})();

console.log(foo[42]);
foo[0] = 'fnord';
console.log(foo[0]);

09-20 13:09