Вопрос по node.js, javascript – Определите getter для объекта, чтобы все неопределенные поиски свойств возвращали «»

9

В основном мне нужно быть в состоянии сделать это:

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__  или же{получить} для того, чтобы вернуть пустую строку для всех неопределенных получателей свойства (обратите внимание, что это отличается от свойства, которое являетсяundefined).

И (глючит)Proxy доступен в узле 0.6.18 через--harmony_proxies флаг. David Murdoch
Да уж. Похоже, V8still working on it. thisgeek
Это не похоже наProxy доступно в любой версии узла. :-( David Murdoch
Proxy доступно на 0.7.8 с флагом командной строки --harmony. David Murdoch
Можете ли вы использоватьproxy? thisgeek

Ваш Ответ

4   ответа
3

Error: User Rate Limit Exceeded

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);
Error: User Rate Limit ExceededgetOrEmptyError: User Rate Limit ExceededObject.prototype.hasOwnProperty.call(obj, name)Error: User Rate Limit Exceededundefined valueError: User Rate Limit Exceeded David Murdoch
Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededhasOwnPropertyError: User Rate Limit ExceededobjError: User Rate Limit ExceededobjError: User Rate Limit ExceededhasOwnPropertyError: User Rate Limit Exceeded David Murdoch
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
8

Вы можете создатьProxyError: User Rate Limit Exceeded

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

Как отмечает автор вопроса Дэвид Мердок, если вы используете узел v0.6.18 (последний стабильный выпуск на момент написания этого поста), вы должны передать--harmony_proxies опция при запуске скрипта:

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

Обратите внимание, что это решение будетnot работать, если вы используетеwithError: User Rate Limit Exceeded

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() в этом примереincomplete, УвидетьError: User Rate Limit Exceeded Больше подробностей.

Error: User Rate Limit ExceededObject.getPropertyDescriptorError: User Rate Limit ExceededgetPropertyDescriptorError: User Rate Limit ExceededObject.get**Own**PropertyDescriptorError: User Rate Limit Exceeded David Murdoch
Error: User Rate Limit Exceedednode-proxyError: User Rate Limit Exceedednode-proxy.binError: User Rate Limit ExceededhereError: User Rate Limit ExceededtrueError: User Rate Limit ExceededhasOwnError: User Rate Limit ExceededgetPropertyDescriptorError: User Rate Limit Exceededif( (name in obj) )Error: User Rate Limit Exceeded David Murdoch
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>

Похожие вопросы