400-915-3552 武汉诺和诺诚生物科技有限公司湖北服务中心,湖北省细胞服务中心主营细胞储存、基因检测

您的位置: 资讯 行业资讯

js中null是什么意思(武汉亲子鉴定undefined如何解决 JavaScript 中处理 null 和 undefined 的麻烦事)

0 次浏览 编辑 基因细胞服务中心
2024-08-24 00:00:49

许多 JavaScript 开发人员正在为怎么处理可选值头痛。有什么好办法来最大程度地减少由值(可能为 null、undefined或在运行时未初始化)引起的错误?

在某些情况下,一些语言具有内置功能。在某些静态类型的语言中,你可以说 null 和undefined 是非法值,并且让你的编程语言在编译时抛出 TypeError,但是即使在那些语言中,也无法防止 null 输入在运行时流入程序。

为了更好地处理这类问题,我们需要了解这些值的来源。以下是一些最常见的来源:

用户输入数据库/网络记录未初始化状态函数什么也不会返回

User Input

用户输入

在处理用户输入时,对这些输入进行验证是第一道也是最好的防线。我经常依靠模式验证器来完成这项工作。例如,检查react-jsonschema-form【

https://rjsf-team.github.io/react-jsonschema-form/】。

从流水记录输入

我总是从网络、数据库或用户输入的流水记录中获得的输入。例如我可以用 redux action creators【

https://medium.com/javascript-scene/10-tips-for-better-redux-architecture-69250425af44】 处理undefined 值来合并用户记录: 1const setUser = ({ name = Anonymous, avatar = anon.png } = {}) => ({ 2 type: setUser.type, 3 payload: { 4 name, 5 avatar 6 } 7}); 8setUser.type = userReducer/setUser;

有时,你需要根据数据的当前状态显示不同的内容。如果在初始化所有数据之前显示页面,则可能会遇到这种情况。例如当你向用户显示资金余额时,可能会在加载数据之前意外地显示余额为 $ 0,这会让用户感到不安。你可以创建自定义数据类型,这些数据类型根据当前状态生成不同的输出:

1const createBalance = ({ 2 // default state 3 state = uninitialized, 4 value = createBalance.empty 5} = {}) => ({ 6 __proto__: { 7 uninitialized: () => --, 8 initialized: () => value, 9 format () { 10 return this[this.getState()](value); 11 }, 12 getState: () => state, 13 set: value => { 14 const test = Number(value); 15 assert(!Number.isNaN(test), `setBalance Invalid value: ${ value }`); 16 return createBalance({ 17 state: initialized, 18 value 19 }); 20 } 21 } 22}); 23createBalance.empty = 0;const setBalance = value => createBalance().set(value);const emptyBalanceForDisplay = createBalance() 24 .format(); 25console.log(emptyBalanceForDisplay); // --const balanceForDisplay = setBalance(25) 26 .format(balance); 27console.log(balanceForDisplay); // 25// Uncomment these calls to see the error cases: 28// setBalance(foo); // Error: setBalance Invalid value: foo// Error: createBalance Invalid state: THIS IS NOT VALID 29// createBalance({ state: THIS IS NOT VALID, value: 0 });

上面的代码是一个状态机,不会显示无效状态。当首次创建余额时,它将被设置为uninitialized 状态。如果你在状态 uninitialized 时尝试显示余额,则始终会得到一个占位符值(“--”)。

要更改这个值,你必须通过调用 .set 方法或在 createBalance 工厂中定义的 setBalance来显式的设置一个值。

状态本身是 encapsulated【

https://medium.com/javascript-scene/encapsulation-in-javascript-26be60e325b4】,以保护其免受外界干扰,且可以确保其他函数无法捕获它并将其设置为无效状态。

注意:你可能想知道为什么我要用字符串而不是数字来举例,那是因为用大数字符串来表示货币类型具有十进制精度,可以避免舍入错误,并准确地表示加密货币交易的值,这样可以得到任意有效的十进制精度。

如果你使用 Redux 或 Redux 架构,则可以用 Redux-DSM【

https://github.com/ericelliott/redux-dsm】 声明状态机。

避免创建 `null` 和 `undefined` 值

在你自己的函数中,可以避免一开始就创建 null 或 undefined 值。我想到了很多内置于 JavaScript 的方法。见下文。

避免 null

我从来没有在 JavaScript 中显式地创建过 null 值,因为我从来没有真正看到过它的意义。

从 2015 年以来,JavaScript 开始支持默认值,当你不提供相关参数或属性的值时,这些默认值就会被填写。这些默认设置不适用于 null 值。根据我的经验,这通常是一个错误。为了避免这种陷阱,请不要在 JavaScript 中使用 null。

如果你希望对未初始化的值或空值使用特殊情况,则状态机是更好的选择。

新的 JavaScript 功能

有几个功能可以帮助你处理 nul 或 undefined 值。在撰写本文时,这两个都是第 3 阶段的建议。也许将来你就可以使用它们了。

在撰写本文时,可选链接是第 3 阶段的建议。它是这样的:

1const foo = {}; 2// console.log(foo.bar.baz); // throws error 3console.log(foo.bar?.baz) // undefined

空位合并运算符

“空位合并运算符”也是要添加到规范中的第3阶段建议,它基本上是“后备值运算符”的一种奇特方法。如果左侧的值为 undefined 或 null,则其求值为右侧的值。它是这样的:

1let baz; 2console.log(baz); // undefined 3console.log(baz ?? default baz); 4// default baz// Combine with optional chaining: 5console.log(foo.bar?.baz ?? default baz); 6// default baz

如果未来还没有到来,则需要安装 @

babel/plugin-proposal-optional-chaining 和@

babel/plugin-proposal-nullish-coalescing-operator.。

异步与 Promise

如果某个函数可能没有返回值,那么最好将其包装在 Either 中。在函数式编程中,Either monad 是一种特殊的抽象数据类型,它允许你附加两个不同的代码路径:成功路径或失败路径。 JavaScript 有称为 Promise 的内置异步Either monad-ish 数据类型【

https://medium.com/javascript-scene/javascript-monads-made-simple-7856be57bfe8】。你可以用它对未定义的值进行声明式错误分支: 1const exists = x => x != null;const ifExists = value => exists(value) ? 2 Promise.resolve(value) : 3 Promise.reject(`Invalid value: ${ value }`);ifExists(null).then(log).catch(log); // Invalid value: null 4ifExists(hello).then(log).catch(log); // hello

你可以根据需要编写一个同步版本,但我把它留给你做练习。如果你对 functors【

https://medium.com/javascript-scene/functors-categories-61e031bac53f】 和 monads【

https://medium.com/javascript-scene/javascript-monads-made-simple-7856be57bfe8】 比较熟悉,那么过程将变得更加容易;如果这听起来令人生畏,也不用担心,只不过是使用 promise。它们是内置的,并且在大多数情况下都可以正常工作。

Maybe 数组

数组实现一个 map 方法,该方法采用一个应用于每个元素数组的函数。如果数组为空,则永远不会调用该函数。换句话说,JavaScript 中的数组可以填补 Haskell 等语言中 Maybe 的角色。

什么是Maybe?

Maybe 是一种特殊的抽象数据类型,它封装了一个可选值。数据类型有两种形式:

Just — 包含一个值Nothing — 没有值

其核心思想是这样的:

1const log = x => console.log(x); 2const exists = x => x != null;const Just = value => ({ 3 map: f => Just(f(value)), 4});const Nothing = () => ({ 5 map: () => Nothing(), 6});const Maybe = value => exists(value) ? 7 Just(value) : 8 Nothing();const empty = undefined; 9Maybe(empty).map(log); // does not log 10Maybe(Maybe Foo).map(log); // logs "Maybe Foo"

上面仅是演示这个概念的例子。你可以围绕 Maybe 建立一个有用函数的完整库去实现其他操作,如 flatMap 和 flat(在编写多个 Maybe 返回函数时,避免使用 Just(Just(value)))。但是 JavaScript 已经有了一种数据类型,该数据类型可以直接实现这些功能,它就是数组。

如果你要创建一个可能会也可能不会产生结果的函数(尤其是可能有多个结果),则下面是一个很好的例子。

1const log = x => console.log(x); 2const exists = x => x != null;const arr = [1,2,3]; 3const find = (p, list) => [list.find(p)].filter(exists); 4find(x => x > 3, arr).map(log); // does not log anything 5find(x => x < 3, arr).map(log); // logs 1

我发现不在空列表上调用 map 对于避免 null 和 undefined 值非常有用,但是请记住,如果数组中包含 null 和 undefined 值,它将调用函数处理这些值,因此,如果你的函数可能会产生 null 或 undefined,则需要将其从返回的数组中过滤掉。这可能会改变集合的长度。

在 Haskell 中,有一个函数maybe(类似 map)将一个函数应用于一个值。但是该值是可选的,并封装在 Maybe 中。我们可以用 JavaScript 的 Array 数据类型做同样的事:

1// maybe = b => (a => b) => [a] => b 2const maybe = (fallback, f = () => {}) => arr => 3 arr.map(f)[0] || fallback;// turn a value (or null/undefined) into a maybeArray 4const toMaybeArray = value => [value].filter(exists);// maybe multiply the contents of an array by 2, 5// default to 0 if the array is empty 6const maybeDouble = maybe(0, x => x * 2);const emptyArray = toMaybeArray(null); 7const maybe2 = toMaybeArray(2);// logs: "maybeDouble with fallback: 0" 8console.log(maybeDouble with fallback: , maybeDouble(emptyArray)); 9// logs: "maybeDouble(maybe2): 4" 10console.log(maybeDouble(maybe2): , maybeDouble(maybe2));

maybe 会使用一个后备值,然后是一个映射到 may 数组上的函数,然后是一个 may 数组(一个数组包含一个值,或者什么都不包含),然后返回将该函数应用于数组内容的结果,或者返回数组为空时的值。

如果你想获取更多Java学习资料和行业动态,可以关注“武汉千锋”微信公众号!


js中null是什么意思(武汉亲子鉴定undefined如何解决 JavaScript 中处理 null 和 undefined 的麻烦事)

文章内容可能有引用其它网络内容,如有侵害您的权益,请联系我们免费删除:https://www.whnhnc.com/hangye/

  • 细胞存储问答
  • 亲子鉴定了解
  • 细胞应用咨询
  • 基因检测咨询
  • 其它百科咨询
微信扫一扫

Copyright@2011-2018 All Rights Reserved 版权所有: © 2020 武汉诺和诺诚生物科技有限公司 鄂ICP备2022020202号-5

首页 / 亲子鉴定 / 细胞储存 /服务项目 /