![](/img/trans.png)
[英]Checking if any variable in object have null/undefined/emptyString('')
[英]Checking 'undefined' or 'null' of any Object
我正在 Angular 项目上工作,我曾经不时检查对象或其属性上的undefined
或null
。 通常我使用 lodash _.isUndefined()
看下面的例子:
this.selectedItem.filter(i => {
if(_.isUndefined(i.id)) {
this.selectedItem.pop();
}
})
我看不出有什么问题。 但是我在审查上述代码时与我的同事进行了讨论。 他告诉我,如果i
在if
语句之前undefined
,那么它将抛出异常。 相反,他建议我总是像这样检查i
或i.id
:
if(!!i && !!i.id) {
this.selectedItem.pop();
}
我确信他想说的与他在上面的代码中检查undefined
方式不同。 但后来我在想 lodash _.isUndefined
的目的是什么?
任何人都可以让我知道什么是最好的或干净的方法。 因为对我来说!!i && !!i.id
根本不可读。
提前谢谢了。
您可以使用_.isNil()
来检测undefined
或null
。 由于您使用的是Array.filter()
,您希望返回!_.isNil()
。 由于i
应该是一个对象,因此您可以使用!_.isNil(i && i.id)
。
注意:您使用Array.filter()
作为Array.forEach()
。 Array.filter()
的回调应该返回一个布尔值,过滤器的结果是一个新数组。
const selectedItem = [ undefined, {}, { id: 5 }, undefined, { id: 7 }, ]; const result = selectedItem.filter(i => !_.isNil(i && i.id)); console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
您也可以使用_.reject()
并省去添加!
:
const selectedItem = [ undefined, {}, { id: 5 }, undefined, { id: 7 }, ]; const result = _.reject(selectedItem, i => _.isNil(i && i.id)); console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
使用typeof i.id === 'undefined'
来检查undefined
和i.id === null
来检查null
。
您可以编写自己的辅助函数来包装 LoDash 所具有的任何逻辑。 带有!!i && !!i.id
的条件仅查找虚假值(空字符串、 0
等),而不仅仅是null
或undefined
。
引用一个undefined
的变量,因为它的值不会抛出任何错误。 您会因引用未定义的变量而收到ReferenceError
:
> i
Uncaught ReferenceError: i is not defined
如果将未定义的变量传递给函数,则会引发ReferenceError
并且不会执行该函数。
> _.isUndefined(i)
Uncaught ReferenceError: i is not defined
typeof
运算符应该用于安全地检查变量是否已定义:
> typeof i
'undefined'
在您的代码中, i
被定义(它是一个函数参数),因此通过引用它,您不会得到任何ReferenceError
。 当i
被定义、具有undefined
值并且您将其视为对象时,代码将抛出TypeError
:
> var i = undefined; i.id
Uncaught TypeError: Cannot read property 'id' of undefined
你的朋友是对的。 当你这样做时, _.isUndefined(i.id)
你假设i
不是undefined
。 您假设i
是一个具有id
属性的对象,您正在检查它是否为假。
当变量i
本身undefined
时会发生什么? 所以你最终会得到undefined.id
这是一个错误。 因此你可以简单地做到这一点
if(i && i.id) {
// You're good to go
}
以上将检查所有假值,包括0
和""
。 因此,如果您想非常具体,则必须使用typeof
运算符检查两者的类型。
您可以检查i
,如果它不是真实的或者属性是undefined
或null
,那么做一些事情。
if (!i || i.id === undefined || i.id === null) {
this.selectedItem.pop();
}
我可以建议检查if(typeof(element) == "number" && element) {}
在这种情况下, typeof()
部分捕获任何非数字, element
部分应捕获任何NaN
s( typeof(NaN)
返回“number ”)
let words = [null, undefined, 'cheaters', 'pan', 'ear', 'era'] console.log(words.filter(word => word != null));
您可以使用lodash#get (如果根值为 null 或未定义,它将处理),然后使用==
或!=
将输出与 null 进行比较,而不是使用===
或!==
。 如果输出为null
或undefined
则与==
比较为真,而!=
为假。
const selectedItem = [ undefined, {}, {id: null}, { id: 5 }, undefined, { id: 0 }, { id: 7 }, ]; const res = selectedItem.filter(a => _.get(a, 'id') != null); console.log(res);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
使用lodash#get您可以检查任何嵌套级别的存在,而无需随后的&&
像a && ab && abc && abcd
(在d
情况下)查看我的这个答案,以使用lodash#get进行嵌套级别检查
您也可以使用_.isNill
而不是与null
will ==
或!=
进行比较
另一种更“笨拙”的方法是使用_.conforms 。 在我看来,可读性要好得多,您可以直接访问id
因此在此之前没有 undefined 问题:
const items = [ undefined, { id: null}, { id: 5 }, { id: "4" }, { id: undefined }, undefined, { id: 0 }, { id: 7 }, { id: () => 3 } ]; const numbersOnly = _.filter(items, _.conforms({'id': _.isNumber})); console.log('numbers', numbersOnly); const allDefined = _.filter(items, _.conforms({'id': _.negate(_.isUndefined)})); console.log('defined', allDefined); const stringsOnly = _.filter(items, _.conforms({'id': _.isString})); console.log('strings', stringsOnly); const functionsOnly = _.filter(items, _.conforms({'id': _.isFunction})); console.log('functions', functionsOnly);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
Javascript 现在有 (Chrome 80, Safari 13.4) 可选链接 (?.)
可选链运算符 (?.) 允许读取位于连接对象链深处的属性值,而无需明确验证链中的每个引用是否有效。
这意味着如果 i 未定义,您可以检查 id 而不会导致异常
this.selectedItem.filter(i => {
if(i?.id) {
this.selectedItem.pop();
}
})
或者,由于您正在使用过滤器,您可以在过滤器文档中实时检查测试。
const words = ['spray', undefined, 'elite', 'exuberant', 'destruction', 'present'];
const result = words.filter(word => word?.length > 6);
console.log(result);
// expected output: Array ["exuberant", "destruction", "present"]
此外,还值得一提的是,正如@Koushik Chatterjee 的回答所指出的那样, lodash _.get允许您安全地描述深度属性的路径,甚至可以在它不存在的情况下给出默认值。
var object = { 'a': [{ 'b': { 'c': 3 } }] };
_.get(object, ['a', '0', 'b', 'c']);
// => 3
_.get(object, 'a.b.c', 'default');
// => 'default'
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.