简体   繁体   English

避免长点符号链的模式

[英]Pattern to avoid long dot-notation chains

When accessing nested objects using dot notation, I always have to make sure that the previous object exists, which gets pretty exhausting. 使用点表示法访问嵌套对象时,我总是要确保前一个对象存在,这非常耗费精力。

I basically want to avoid long if chains like 我基本上想避免长链如果链

if (a && a.b && a.b.c && a.b.c[0] ... ) { v = a.b.c[0]; }

The only other thing I can think of is via the use of a try catch. 我唯一能想到的是通过使用try catch。

var v; try { v = a.b.c[0].d.e; } catch (e) {}

Is there a better pattern for this? 这有更好的模式吗?

I think you've got the two prettiest solutions already. 我想你已经拥有了两个最漂亮的解决方案。

But note that for something like, say, obj.obj.string.length your first solution will fail if string === "" . 但请注意,对于像obj.obj.string.length这样的东西,如果string === "" ,你的第一个解决方案将会失败。 Since an empty string is falsey, it'll trip the && guard. 由于空字符串是假的,它会使&& guard发送。

But speaking of strings, you could do something like: 但谈到字符串,你可以做类似的事情:

function getNestedProperty(obj, propChain) {
    var props = propChain.slice(0), prop = props.shift();
    if(typeof obj[prop] !== "undefined") {
        if(props.length) {
            return getNestedProperty(obj[prop], props);
        } else {
            return obj[prop];
        }
    }
}

var v = getNestedProperty(a, ["b", "c", 0, "d", "e"]);

Yeah... not too pretty :P 是的......不太漂亮:P

I'd say that, of the solutions proposed, try...catch is probably the simplest way to go 我要说的是,在提出的解决方案中, try...catch可能是最简单的方法

How about this one: 这个怎么样:

var hasProperty = function (object, property) {

    var properties = property.split('.'),
        temp = object;

    while (temp && properties.length) {
        temp = temp[properties.shift()];
    }

    return !!temp;
};

and then use it like: 然后使用它像:

if (a && hasProperty(a, 'b.c.0' ) { v = a.b.c[0]; }

The scenario you are referring to in your question is also called "optional chaining". 您在问题中引用的方案也称为“可选链接”。 Some languages already support it by now – for example C# has so called null-conditional operators which allow you to short-circuit your expressions: 有些语言现在已经支持它 - 例如C#有所谓的空条件运算符 ,它允许你使表达式短路:

var count = customers?[0]?.Orders?.Count();

Unfortunately, this feature has not yet made it into the current JS specifications. 不幸的是,这个功能还没有进入当前的JS规范。

There is an open Stage 1 proposol for "optional chaining" that can be tracked here . “可选链接”有一个开放的第1阶段提议,可在此处进行跟踪。

This would allow you to write... 这可以让你写...

a?.b[3].c?.(x).d

...instead of: ...代替:

a == null ? undefined : a.b[3].c == null ? undefined : a.b[3].c(x).d

If you want to take the risk and use it already at this early stage, you can target it via babel to include it in your project. 如果您想承担风险并在早期阶段使用它,您可以通过babel将其包含在项目中。

It's rather evil, but this should work and doesn't look too horrible: 这是相当邪恶的,但这应该工作,看起来并不太可怕:

var i = !a ? null : !a.b ? null : !a.b.c ? null : !a.b.c.d ? a.b.c.d.e;

The reason for the ! 原因! is to invert the test flag, to allow the success case to be the last expression in the ?: . 是反转测试标志,以允许成功案例成为?:的最后一个表达式。 That allows us to chain them together like this. 这允许我们像这样将它们链接在一起。

Do check the operator precedence if you want to do this for real (I did some very basic tests and I think I got it right). 检查运算符优先级,如果你想真正做这个(我做了一些非常基本的测试,我想我这样做是正确)。 And do expect people to point and laugh if they see it in your code. 并且如果他们在您的代码中看到它, 那么期望人们指出并笑。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM