在对象上定义getter,所有未定义的属性查找返回“”

基本上我需要能够做到这一点:

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}的“全局”等价物,以便为所有未定义的属性获取器返回一个空string(请注意,这与未定义的属性不同)。

您可以创build一个Proxy以便在访问未定义的属性时返回一个空string。

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', '' ] 

请注意,如果您使用此解决scheme将无法正常工作,如下所示:

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

在将代理添加到作用域链时似乎没有调用代理的get方法。

注意:在这个例子中传递给Proxy.create()的代理处理程序是不完整的 。 请参阅代理:有关更多详细信息的常见错误和误解 。

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

使用ES6或更高版本,您可以使用代理,就像接受的答案一样。 但是,如果你坚持使用ES5,这是一个答案。

有了ES5,你将不得不创build自己的类,就像这个快速的例子

 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