基本上我需要能够做到这一点:
var obj = {"foo":"bar"},
arr = [];
with( obj ){
arr.push( foo );
arr.push( notDefinedOnObj ); // fails with 'ReferenceError: notDefinedOnObj is not defined'
}
console.log(arr); // ["bar", ""] <- this is what it should be.
我正在寻找一个“全局”等价的{}.__defineGetter__
或{get},以便为所有未定义的属性getter返回一个空字符串(请注意,这与{{{}的属性不同1}})。
答案 0 :(得分:9)
只要访问未定义的属性,就可以创建Proxy
以返回空字符串。
app.js
:
var obj = {"foo":"bar"},
arr = [],
p = Proxy.create({
get: function(proxy, name) {
return obj[name] === undefined ? '' : obj[name];
}
});
arr.push( p.foo );
arr.push( p.notDefinedOnObj );
console.log(arr);
正如问题作者David Murdoch指出的那样,如果您使用的是节点v0.6.18(编写本文时的最新稳定版本),则必须在运行脚本时传递--harmony_proxies
选项:
$ node --harmony_proxies app.js
[ 'bar', '' ]
请注意,如果您使用with
,此解决方案将不,如:
var obj = {"foo":"bar"},
arr = [],
p = Proxy.create({
get: function(proxy, name) {
return obj[name] === undefined ? '' : obj[name];
}
});
with ( p ) {
arr.push( foo ); // ReferenceError: foo is not defined
arr.push( notDefinedOnObj );
}
console.log(arr);
将代理添加到范围链时, with
似乎没有调用代理的get
方法。
注意:传递给Proxy.create()
的代理处理程序就是不完整。有关详细信息,请参阅Proxy: Common mistakes and misunderstanding。
答案 1 :(得分:3)
javascript中没有全局缺失的成员处理程序。您需要引入一个函数来抽象出行为
function getOrEmpty(obj, name) {
if (!obj.hasOwnProperty(name)) {
return "";
}
return obj[name];
}
var obj = {"foo":"bar"},
arr = [];
arr.push(getOrEmpty(obj, "foo"));
arr.push(getOrEmpty(obj, "someUndefinedProperty"));
console.log(arr);
答案 2 :(得分:1)
使用ES6及更高版本,您可以使用代理,就像建议的接受答案一样。但是如果你被ES5困住,这就是答案。
使用ES5,你必须创建自己的类,就像在这个简单的例子中一样
function StrictObject() {
var values = Object.create(null);
this.set = function (key, value) {
values[key] = value;
};
this.get = function (key) {
if (!(key in values)) {
throw new Error("Could not find " + key);
}
return values[key];
};
}
var obj = new StrictObject();
obj.set('dad', 'homer');
console.log(obj.get('dad')); // homer
console.log(obj.get('uncle')); // throws error
答案 3 :(得分:1)
Proxy.create
似乎不再是一件事。
这是一个新的例子:
const p = new Proxy({foo:1}, {
get(obj, name) {
return Object.hasOwnProperty.call(obj, name) ? obj[name] : '';
}
})
console.log(p.foo);
console.log(p.bar);
&#13;
你可以[ab]使用它做一些有趣的小事,比如创建React助手:
const cc = new Proxy(Object.create(null), {
get(proxy, name) {
return ({className,...props}) => React.createElement(name, {className: classcat(className), ...props})
}
})
<cc.tr className={[theme.tr,theme.hrow]}>...</cc.tr>
// renders: <tr class="datatable_tr--2vnM1 datatable_hrow--_PG2G">...</tr>