我们可以在javascript中的对象上指定通用的getter吗?

时间:2018-06-21 07:53:35

标签: javascript object getter

想做

properties.email.value而不会触发类似Can't read 'value' of 'undefined'

的错误

但是,我不想做

properties.email && properties.email.value,但我不想使用帮助器,例如:get(properties, 'email.value')


我真的很想保留语法properties.email.value

我可以通过以下方法解决此问题:

Object.defineProperty(properties, 'email', {
 get: () => properties.email && properties.email.value,
 enumerable: true,
 configurable: true
});

现在getter负责我的安全检查。完美。

但是我也希望能够安全地进行properties.name.value。 但是由于properties对象来自API(json),因此我不知道properties的完整列表。

因此,有没有办法将这种“神奇的” get语法用于任何道具访问,例如:properties[ANYTHING].value

3 个答案:

答案 0 :(得分:3)

好的,我有类似的东西。

但是您必须以这种方式创建properties

希望获得帮助:)

var properties = {
  phone : {
    value: "123456789"
  }  
}

var handler = {
  get: function(target, name) {
    return target.hasOwnProperty(name) ? target[name] : {};
  }
};

var new_properties = new Proxy(properties, handler);

console.log("phone.value = " + new_properties.phone.value);

console.log("email.value = " + new_properties.email.value);

new_properties.email = {
  value: 1
};

console.log("email.value after assign = " + new_properties.email.value);

文档参考here

已编辑

即使原始properties对象未知,这种用法也能正常工作。

答案 1 :(得分:2)

您可以使用Proxy来获取已知属性和未知属性的自定义结果。

要更改属性,可以采用相同的方法并设置值。

var properties = { email: { value: 'foo@example.com' } },
    proxy = new Proxy(
        properties,
        {
            get: function(target, prop, receiver) {
                if (prop in target) {
                    return target[prop] && target[prop].value
                } else {
                    return;
                }
            },
            set: function(target, prop, value) {
                if (prop in target) {
                    target[prop].value = value;
                } else {
                    target[prop] = { value };
                }
            }
        }
    );

console.log(proxy.email);
console.log(proxy.bar);

proxy.email = '41';
console.log(proxy.email);

答案 2 :(得分:0)

我不敢相信我正在这样做...

var wordlength = 7;
var alphabet="abcdefghijklmnopqrstuvwxyz";
alphabet += alphabet.toUpperCase() + "0123456789_";
var alen = alphabet.length;
var buildWord = function(number){
    if(number===0){
        return '';
    }
    return alphabet[number%alen]+buildWord(Math.floor(number/alen));
};
var total = Math.pow(alen, wordlength);
for(var i = 1; i<total; i++){
    var w = buildWord(i);
    if(isNaN(w[0]) && Object.prototype[w]===undefined){
        Object.prototype[w]={};
    }
}