为什么这个三元组抛出错误而不是求值为 false?

why is this ternary throwing an error instead of evaluating to false?

我正在尝试测试一个对象的真实性 属性。它是否存在并具有值使用该值,如果不存在则将默认值添加到另一个对象。

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.

虽然我在这里遇到错误。我认为它会 return 未定义,因此会将 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

查看此 key/value 对是否一直存在于树中的最佳方法是什么,如果存在则使用该值,否则设置假值?

您正在分配给一个名为 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.

您可以测试一个对象是否存在,但您不能测试一个 属性 的不存在的对象是否存在,这就是您的代码在 [=11= 时尝试做的事情] 没有传递给函数。

在尝试使用某个参数之前,您需要让您的函数测试该参数是否已传入。而且,鉴于您的代码中有两个地方需要进行此测试,因此不使用三元组而是使用传统的 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);

也许 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;
    }
}