请教:判断集合元素属性真值的JS函数为何失效?
问题分析:集合元素属性真值校验算法失效排查
我需要检查集合中的所有元素是否均包含指定属性,且该属性的值为真值。我编写了如下算法,多数场景下运行正常,但在某案例中失效,无法定位原因,恳请各位帮忙分析。
代码如下:function truthCheck(collection, pre) { // Is everyone being true for (var i = 0; i < collection.length; i++) { //console.log(collection[i].user); if (collection[i].hasOwnProperty(pre)) { if (collection[i][pre] == true) continue; } return false; } return true; }
为啥你的代码会失效?
我一眼就看到两个关键问题,这就是导致部分场景判断错误的根源:
== true的判断太死板了
JavaScript里的「真值」范围比你想的广得多——非零数字、非空字符串、对象、数组这些都属于真值,但它们和true用==比较时不一定返回true。比如属性值是28或者"hello"时,明明是真值,但28 == true会返回false,"hello" == true也会返回false,这时候你的代码就会错误地返回false。逻辑分支的小漏洞
当元素有指定属性,但属性值是假值(比如0、""、null)时,你的内层if不成立,会直接走到return false,这部分是对的;但如果属性值是「非true的真值」,同样会触发return false,这就完全不符合你的需求了。
修正后的代码方案
我们只需要把判断逻辑改成直接检查属性值是否为真值,同时确保元素存在该属性就行,逻辑可以简化很多:
方案一:保留for循环的写法
function truthCheck(collection, pre) { for (var i = 0; i < collection.length; i++) { // 只要元素没这个属性,或者属性值是假值,直接返回false if (!collection[i].hasOwnProperty(pre) || !collection[i][pre]) { return false; } } return true; }
方案二:用数组every方法更简洁
function truthCheck(collection, pre) { // every方法会遍历所有元素,只有全部满足条件才返回true return collection.every(item => item.hasOwnProperty(pre) && Boolean(item[pre])); }
验证失效场景举个例子
比如测试这个场景:
truthCheck([{name: "Antony", age: 28}, {name: "Jane", age: 30}], "age");
你的原代码会返回false(因为28 == true不成立),但实际上年龄是有效的真值;修正后的代码会正确返回true。
再比如属性值是字符串"yes"的情况:
truthCheck([{active: "yes"}, {active: true}], "active");
原代码会错误返回false,修正后的代码则会正确返回true。
内容的提问来源于stack exchange,提问作者Antony Castle
相关产品推荐
相关产品推荐

