Как я перемещаю объект JavaScript и проверяю нули?
Скажем, у меня есть объект JavaScript, например:
var obj = {};
obj.computers = {};
obj.computers.favorite = "Commodore 64";
obj.computers.popular = "Apple";
Теперь я могу легко проверить нулевое значение:
if(obj != 'undefined' && obj != null) {
if(obj.computers != 'undefined' && obj.computers != null)) {
.....
Как вы можете видеть, если мне нужно определить, был ли установлен obj.computers.favorite
, я должен действительно вставить некоторую условную логику. Некоторые из наших объектов идут на глубину 3, 4, 5.
Вот что я хотел бы сделать:
var fav = obj.computers.favorite || 'Unknown';
Но я понимаю, что мне нужно будет обернуть это каким-то способом. Что-то вроде:
var fav = getValueOrDefault(obj.computers.favorite, 'Unknown');
Предложения оценены.
Спасибо
ИЗМЕНИТЬ
Моя проверка на 'undefined' на самом деле не используется. Он просто вышел из моей головы, задавая вопрос. лол
Но мне было интересно, могу ли я просто вставить в try/catch и сбросить default, если исключение?
function(obj, default) {
try {
if(obj != null) {
return obj;
} else {
return default;
}
} catch(ex) {
return default;
}
}
Кроме того, благодаря Шуси для указания избыточных варов.
Ответы
Ответ 1
Вы можете сделать это с помощью вспомогательной функции. Если я правильно понимаю вашу проблему, ваши объекты могут иметь произвольные глубокие объекты, и вы хотите получить доступ к этим произвольным вложенным свойствам без загромождения кода. Я построил функцию Nested
, которая позволяет вам get()
произвольные свойства, если они установлены, или по умолчанию, если они не являются.
var Nested = function() {};
// prop is a dot-separated path like "foo.bar.baz"
Nested.prototype.get = function(prop, _default) {
var current = this;
$.each(prop.split("."), function(i, e) {
current = current[e] || undefined;
if (current == undefined)
return false;
});
return current || _default;
}
Затем вы можете написать код, подобный этому
var fav = obj.get("computers.favourite", "Linux");
// this emulates
var fav = obj.computers.favourite || "Linux"; // throws error
Как вы можете видеть, это не намного больше печатает. Конечно, он не похож на обычный Javascript... Вот скрипка.
Ответ 2
Вы действительно можете написать:
(obj && obj.computers && obj.computers.favorite) || 'Unknown'
Ответ 3
Я написал это, чтобы помочь вам разобраться с одним из ваших вопросов: "Мне нужно проверить, установлен ли obj.computers.favorite".
Object.prototype.isset = function (/* string */ full_path)
{
var props = full_path.split('.');
var self = this; /* note that self is usually the window object */
for (var ii = 0; ii < props.length; ++ii)
{
var prop = props[ii];
var hasMoreComing = ii < props.length - 1 ? true : false;
if (self[prop] !== null && typeof self[prop] === 'object' && hasMoreComing)
{
self = self[prop];
continue; // Move up one level.
}
else if (hasMoreComing)
return false; // ..because user queries a subproperty of a value type
return self.hasOwnProperty(prop);
}
};
Test-код:
var test = {};
test.kuk = {};
console.log( test.isset('kuk') ); // Prints true.
test.kuk.fitta = {};
console.log( test.isset('kuk.fitta') ); // Prints true.
test.kuk.fitta = null;
console.log( test.isset('kuk.fitta') ); // Prints true.
test.kuk.fitta = undefined;
console.log( test.isset('kuk.fitta') ); // Prints true
delete test.kuk.fitta;
console.log( test.isset('kuk.fitta') ); // Prints false
test.kuk.fitta = 123;
console.log( test.isset('kuk.fitta.doesnt.exist') ); // Prints false
Ответ 4
следующая функция примет строку как параметр и объект возврата, если существует
function getValueOrDefault(str , obj, deflt){
var a = str.split("."); o = obj;
for(var i =0; i < a.length; i++){
o = obj[a[i]];
if(!o){
return deflt;
}
}
return o;
}
var obj = {};
obj.computers = {};
obj.computers.favorite = "Commodore 64";
obj.computers.popular = "Apple";
getValueOrDefault('computers.favorite', obj, 'Unknown');
Примечание. Вы не должны использовать var при назначении свойств объекту, например. var obj.computers.favorite
является ошибкой SYNTAX.
Ответ 5
К сожалению, нет очень простого способа обойти это, но вам не нужно проверять как null, так и undefined. Поскольку null и undefined являются ложными, вы можете просто:
if (obj && obj.computers) {
var fav = obj.computers.favorite || 'unknown';
}
На самом деле это не распространяется на вашу жалобу, но она менее болезненна, чем вы думаете.
Ответ 6
Вы также можете сделать это с помощью функции reduce
JavaScript ES5:
function get(root, member) {
return member.split('.').reduce((acc, value) => {
return (acc && typeof acc[value] !== 'undefined') ? acc[value] : undefined
}, root);
}
Он создает массив из строки-члена, затем аккумулятор постепенно перемещается внутри объекта по мере уменьшения числа членов.
Вы можете использовать это так, даже с массивами:
let obj = {
computers : {
favorite : "Commodore 64",
popular : "Apple",
list: [
{
sn : "TDGE52343FD76",
price: "9867.99",
options: {
fanless: true
}
}
]
}
}
get(obj, 'computers.popular');
// => "Apple"
get(obj, 'computers.list.0.sn');
// => "TDGE52343FD76"
get(obj, 'computers.list.0.options.fanless');
// => true
get(obj, 'computers.list.0.options.runsWithoutEletricity');
// => undefined
get(obj, 'computers.list.0.options.runsWithoutEletricity') || "too bad..." ;
// => "too bad..."
Существует кодовая ручка для безопасного обхода объекта js