10

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

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__ or {get}等效的“全局” ,以便为所有未定义的属性 getter 返回一个空字符串(请注意,这与 is 的属性不同undefined)。

4

4 回答 4

11

您可以创建一个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 所指出的,如果您使用的是 node 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);

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

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

于 2012-05-24T19:50:10.173 回答
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);
于 2012-05-23T21:15:27.277 回答
1

使用 ES6 及更高版本,您可以使用 Proxy,就像建议的接受答案一样。但是如果你被 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
于 2016-05-02T10:27:09.307 回答
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);

你可以 [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>
于 2018-03-29T18:23:05.733 回答