Define getter on object so all undefined property lookups return ""

Basically I need to be able to do this:

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.

I'm looking for a "global" equivalent of {}.__defineGetter__ or {get} in order to return an empty string for all undefined property getters (note that this is different than a property that is undefined).

You can create a Proxy to return an empty string whenever undefined properties are accessed.

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

As question author David Murdoch notes, if you are using node v0.6.18 (the latest stable release at the time this post was written), you must pass the --harmony_proxies option when you run the script:

$ node --harmony_proxies app.js
[ 'bar', '' ]

Note that this solution will not work if you use with, as in:

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 does not seem to call the proxy's get method when adding the proxy to the scope chain.

Note: the proxy handler passed to Proxy.create() in this is example is incomplete. See Proxy: Common mistakes and misunderstanding for more details.

There is no global missing member handler in javascript. You'll need to introduce a function to abstract out the behavior

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