Почему эта троичная ошибка выдает ошибку, а не оценивается как ложная?
Я пытаюсь проверить истинность свойства объекта. Если оно существует и имеет значение, используйте это значение, а если его нет, добавьте значение по умолчанию к другому объекту.
const initNetwork = ( setupObj ) => {
let obj = {};
obj = Object.assign({}, setupObj);
obj.eth0 = obj.eth0 ? obj.eth0 : {};
obj.wlan0 = obj.wlan0 ? obj.wlan0 : {};
obj.eth0.server = obj.eth0.server ? obj.eth0.server : {};
obj.wlan0.client = obj.wlan0.client ? obj.wlan0.client : {};
obj.wlan0.server = obj.wlan0.server? obj.wlan0.server : {};
obj.eth0.mac = null;
obj.wlan0.mac = null;
obj.eth0.server.address = setupObj.eth0.server.address ? setupObj.eth0.server.address : "10.0.0.1";
}
initNetwork(); // intentionally leaving this empty to test setting default values.
Я получаю ошибку здесь, хотя. Я думал, что он вернет undefined и поэтому установит obj.eth0.server.address в ложное значение "10.0.0.1".
obj.eth0.server.address = setupObj.eth0.server.address ? setupObj.eth0.server.address : "10.0.0.1";
^
TypeError: Cannot read property 'eth0' of undefined
Как лучше всего увидеть, существует ли эта пара ключ / значение на всем протяжении дерева, и если да, то использовать это значение, в противном случае установить значение false?
3 ответа
Вы присваиваете новый объект с именем obj
так что ваш чек должен быть против obj
,
В этой ситуации setupObj
всегда будет undefined
,
Вы можете добавить еще одно условие для setupObj
с использованием &&
оператор:
obj.eth0.server.address = (setupObj && setupObj.eth0.server.address) ? setupObj.eth0.server.address : "10.0.0.1";
Конечно, рекомендуется проверять каждый уровень вложенных объектов.
Бегущий пример:
const initNetwork = ( setupObj ) => {
let obj = {};
obj = Object.assign({}, setupObj);
obj.eth0 = obj.eth0 ? obj.eth0 : {};
obj.wlan0 = obj.wlan0 ? obj.wlan0 : {};
obj.eth0.server = obj.eth0.server ? obj.eth0.server : {};
obj.wlan0.client = obj.wlan0.client ? obj.wlan0.client : {};
obj.wlan0.server = obj.wlan0.server? obj.wlan0.server : {};
obj.eth0.mac = null;
obj.wlan0.mac = null;
obj.eth0.server.address = (setupObj && setupObj.eth0.server.address) ? setupObj.eth0.server.address : "10.0.0.1";
}
initNetwork(); // intentionally leaving this empty to test setting default values.
Возможно, блок try / catch поможет вам избавиться от лишнего кода:
try {
obj.eth0.server.address = setupObj.eth0.server.address;
} catch (e) {
if (e instanceof TypeError) {
obj.eth0.server.address = '10.0.0.1';
} else {
throw e;
}
}
Вы можете проверить, существует ли объект, но вы не можете проверить, существует ли свойство несуществующего объекта, и именно это пытается делать ваш код, когда setupObj
не передается в функцию.
Вам нужна ваша функция, чтобы проверить, был ли передан аргумент, прежде чем пытаться использовать этот аргумент. И, учитывая, что в вашем коде есть два места, где вам нужно выполнить этот тест, имеет больше смысла не использовать троичный и вместо этого использовать традиционный if
,
Функция должна быть следующей (вы можете запустить этот код, чтобы увидеть его в действии):
const initNetwork = ( setupObj ) => {
let obj = null; // Don't set a value here because it's just going to be overridden
// If setupObj exists....
if(setupObj){
// Use it:
obj = Object.assign({}, setupObj);
obj.eth0.server.address = setupObj.eth0.server.address;
} else {
// But, if not, you need to set up your defaults:
obj = {
eth0: {
server: {
address: "10.0.0.1"
},
mac: null
},
wlan0 : {
server: {},
client: {},
mac:null
}
};
}
// After that, you can proceed as you need to...
// TEST:
console.log(obj.eth0.server.address);
}
initNetwork(); // intentionally leaving this empty to test setting default values.
// Now a test for when a valid setupObj is passed:
var objTest = {
eth0: {
server: {
address: "192.168.1.1"
},
mac: null
},
wlan0 : {
server: {},
client: {},
mac:null
}
};
initNetwork(objTest);