繁体   English   中英

检查任何对象的“未定义”或“空”

[英]Checking 'undefined' or 'null' of any Object

我正在 Angular 项目上工作,我曾经不时检查对象或其属性上的undefinednull 通常我使用 lodash _.isUndefined()看下面的例子:

this.selectedItem.filter(i => {
    if(_.isUndefined(i.id)) {
      this.selectedItem.pop();
    }
})

我看不出有什么问题。 但是我在审查上述代码时与我的同事进行了讨论。 他告诉我,如果iif语句之前undefined ,那么它将抛出异常。 相反,他建议我总是像这样检查ii.id

if(!!i && !!i.id) {
      this.selectedItem.pop();
}

我确信他想说的与他在上面的代码中检查undefined方式不同。 但后来我在想 lodash _.isUndefined的目的是什么?

任何人都可以让我知道什么是最好的或干净的方法。 因为对我来说!!i && !!i.id根本不可读。

提前谢谢了。

您可以使用_.isNil()来检测undefinednull 由于您使用的是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'来检查undefinedi.id === null来检查null

您可以编写自己的辅助函数来包装 LoDash 所具有的任何逻辑。 带有!!i && !!i.id的条件仅查找虚假值(空字符串、 0等),而不仅仅是nullundefined

引用一个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 ,如果它不是真实的或者属性是undefinednull ,那么做一些事情。

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 进行比较,而不是使用===!== 如果输出为nullundefined则与==比较为真,而!=为假。

 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.

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