2014-11-07 2 views
3

Скажите, что я хочу получить a.b.c.d, и я не уверен, есть ли b или c. 'наивное' чек будет:Есть ли собственный способ проанализировать объект JavaScript?

if (a.b && a.b.c && a.b.c.d == 5) doSomething(a.b.c.d); 

Я думал над этим и написал эту функцию, которая улучшает это:

Object.prototype.parse = function (keys, def) { 
    return keys.split('.').reduce(function (prev, curr) { 
    if (prev) { 
     return prev[curr]; 
    } 
    }, this) || def; 

}; 

И вы бы использовать его как это:

var a = { 
    b: { 
    c: { 
     d: 5 
    } 
    } 
}; 

console.log(a.parse('b.c.d', 3)); // If b, c or d are undefined return 3 

Но мне интересно, не хватает ли я лучшего, родного способа добиться этого, вместо того, чтобы добавлять эту функцию в проекты.

Спасибо!

+2

Вы также можете просто поместить обработчик исключений вокруг него и просто получить доступ к 'var x = a.b.c.d'. Он либо преуспеет, либо выдает исключение, либо возвращает 'undefined' (если отсутствует только' d'). – jfriend00

+2

Для этого есть библиотека под названием '' dotty' '(https://github.com/deoxxa/dotty). – Paul

+0

@ jfriend00 Решение try..catch значительно медленнее, поскольку оно отключает оптимизацию интерпретатора – Ben

ответ

-2

Единственный родной способ - eval, но я бы не рекомендовал его, как можно использовать для выполнения произвольного кода. Это может быть ОК, но не в том случае, если строки стиля «a.b.c.d» исходят от ненадежных пользователей. Я бы придерживался вашего решения с ручным управлением или использовал dotty.

var a = { 
    b: { 
    c: { 
     d: 5 
    } 
    } 
}; 
console.log(eval("a.b.c.d")); 

Eval() выбросит ту же ошибку, что родной эквивалент бы, когда б или не определены, так что вы должны будете обернуть попробовать {} поймать {} блока.

+0

Я думаю, что он пытается решить ошибку «Uncaught ReferenceError: a не определен». –

+0

Можете ли вы проголосовать, объясните сами. Благодарю. – Adam

+0

Уважаемый downvoter, я знаю, что вам может не понравиться eval - я этого не делаю, но это полностью отвечает на исходный вопрос. – Adam

-2

Я думаю, что у меня есть другое решение этой проблемы, я пытался достичь этого в течение нескольких минут. Если вы работаете с областью окна, вы можете использовать мою функцию, чтобы увидеть, существует ли объект или вернуть значение по умолчанию.

function parseObj(obj){ 
    try{ 
     return eval(obj); 
    }catch(e){ 
     return null; 
    } 
} 

Использование

alert(parseObj("a.b.c.d")); 

Я не знаю, если это то, что вы ищете, но я уверен, что это даст вам еще одну идею. Хорошей работы.

+0

Интересно, что за то, что он проголосовал за истинный ответ. –

+0

Если вы, ребята, проголосуете, дайте повод! –

1

Может быть не совсем то, что вы просили, но, вероятно, как можно ближе к «родным», как вы можете получить (чуть более компактный вариант разделения/Reduce фрагмент кода вы предоставили):

var a = {b:{c:{d:5}}}; 
("b.c.d").split(".").reduce(function(p,c){return p && p[c];},a); //5 
("b.c.e").split(".").reduce(function(p,c){return p && p[c];},a); //undefined 

Если бы вы были надеясь на решение со строкой, как "a.b.c.d", тогда вам нужно будет использовать eval (не recoomended), или объект a должен быть глобальным (также не рекомендуется), или объект должен быть свойством другого объекта, который является немного самонадеянное.

Смежные вопросы