0


【前端】深入理解 JavaScript 逻辑运算符的优先级与短路求值机制


在这里插入图片描述
博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: 前端


文章目录


在这里插入图片描述


💯前言

  • 在编写JavaScript程序时,逻辑运算符&&(逻辑与)和||(逻辑或)是常用的构造工具,能够简洁地实现逻辑判断和条件分支。然而,在处理复杂逻辑时,这些运算符的优先级和短路求值特性可能导致混淆和误解。对于开发者而言,深入理解这些运算符的工作机制不仅有助于编写高效、健壮的代码,还可以减少调试中遇到的意外情况。本文旨在深入探讨JavaScript中逻辑运算符的优先级、短路求值,以及它们在编写高效、健壮代码中的应用。 JavaScript在这里插入图片描述

💯案例背景

  • 我有一次在JavaScript中写了一个函数实现类似数组的push功能,在判断arguments的第 0 项是否为数组的这一行采用了逻辑运算符,发现自己对于逻辑运算符理解并不是很清晰确切,所以本文就是通过这段逻辑运算符代码来引入这一讨论。在这里插入图片描述var arr =[1,2,3];functionpush(){var arr = Array.isArray(arguments[0])&& arguments[0]||[]; console.log(arr);var argLen = arguments.length;for(var i =1; i < argLen; i++){var len = arr.length; arr[len]= arguments[i];}return arr;}console.log(push([1,2,3],4,5,6,7));

该代码结合使用了

&&

||

两个逻辑运算符,如下所示:

var arr = Array.isArray(arguments[0])&& arguments[0]||[];

尽管这段代码看起来很简洁,但对于缺乏深入理解逻辑运算符优先级的程序员而言,容易产生混淆。特别是当

&&

||

结合在一起时,其执行顺序并不直观。为了全面理解这段代码的逻辑,我们需要首先明确 JavaScript 中运算符的优先级及逻辑运算符的短路求值机制。


💯逻辑运算符的优先级与短路求值

在这里插入图片描述


运算符优先级的概念

在这里插入图片描述

运算符优先级决定了当一个表达式包含多个运算符时,哪些运算符优先执行。在 JavaScript 中,不同运算符具有不同的优先级,这意味着在复杂表达式中,优先级高的运算符将首先被计算。例如,对于表达式

1 + 2 * 3

,乘法运算符

*

的优先级高于加法运算符

+

,因此乘法首先执行,最终结果为

1 + 6 = 7

在逻辑运算符中,

&&

的优先级高于

||

,这意味着在包含这两个运算符的表达式中,

&&

会先执行,然后才是

||


短路求值的概念

在这里插入图片描述

短路求值是一种逻辑运算符的计算特性。在

&&

||

运算的过程中,JavaScript 会依据操作数的值来决定是否继续计算下一个操作数,或者直接返回最终结果。

  • 逻辑与 (&&) 的短路求值 :如果第一个操作数为 false,则整个表达式的结果必然为 false,此时不再计算第二个操作数。例如,false && anything 的结果一定是 false,因为无论 anything 的值是什么,只要第一个操作数为 false,结果就是 false
  • 逻辑或 (||) 的短路求值 :如果第一个操作数为 true,整个表达式的结果就是 true,无需再计算第二个操作数。例如,true || anything 的结果总是 true,因为只要有一个操作数为 true,整个表达式的值就是 true

理解这些特性后,我们便能够更深入地分析复杂的逻辑表达式。


💯分析案例代码的执行过程

在这里插入图片描述

回到我们的示例代码:

var arr = Array.isArray(arguments[0])&& arguments[0]||[];

理解这段代码的执行过程需要按照逻辑运算符的优先级和短路求值规则进行逐步分析。


第一步:执行

&&

运算

在这里插入图片描述

首先执行的是

Array.isArray(arguments[0]) && arguments[0]

,因为

&&

的优先级高于

||

  • Array.isArray(arguments[0]) :这部分代码用于检查 arguments[0] 是否是一个数组。
  • 如果 arguments[0] 是一个数组,则表达式的值为 arguments[0]
  • 如果 arguments[0] 不是数组或未定义,则表达式的值为 false

第二步:执行

||

运算

在这里插入图片描述

接下来执行

&&

运算后的结果与

|| []

进行逻辑或运算。

  • 如果 && 部分的结果是一个数组(即 arguments[0] 是数组),则 || 运算符左边的值为 true,直接返回该数组。
  • 如果 && 部分的结果是 false,则 || 会返回右侧的值 [],即空数组。

💯运算示例

在这里插入图片描述

以下示例演示了不同输入下该段代码的执行过程。


示例 1:

arguments[0]

为数组

在这里插入图片描述

functiontest(){var arr = Array.isArray(arguments[0])&& arguments[0]||[];
    console.log(arr);}test([1,2,3]);// 输出:[1, 2, 3]
  • 在此示例中,arguments[0][1, 2, 3],即数组。
  • Array.isArray(arguments[0]) 返回 true,因此 && 的右侧 arguments[0] 被返回,即 [1, 2, 3]
  • 因为 && 部分结果为数组,|| 操作符不会再执行右侧的 [],最终结果为 [1, 2, 3]

示例 2:

arguments[0]

不是数组

在这里插入图片描述

test("not an array");// 输出:[]
  • 在此示例中,arguments[0]"not an array",不是数组。
  • Array.isArray(arguments[0]) 返回 false,因此 && 部分的结果为 false
  • || 操作符执行右侧的 [],最终结果为空数组 []

示例 3:未传入参数

在这里插入图片描述

test();// 输出:[]
  • 在这种情况下,arguments[0]undefined
  • Array.isArray(arguments[0]) 返回 false,因此 && 部分的结果为 false
  • || 操作符执行右侧的 [],最终结果为空数组 []

💯按顺序计算运算符的重要性

  • 在这里插入图片描述 在逻辑运算中,不能直接将 || [] 看作一个整体,而必须依据运算符优先级和计算顺序来进行判断。&&|| 都是从左到右逐步执行的。在这里插入图片描述
  1. 首先计算 && 部分 :由于 && 的优先级更高,必须首先计算 Array.isArray(arguments[0]) && arguments[0]
  2. 然后计算 || 部分 :根据 && 的计算结果,执行 || []。若前者结果为 false,则返回空数组 []

💯逻辑运算符的最佳实践

在这里插入图片描述

了解了这些基础知识之后,我们可以总结出一些逻辑运算符的最佳实践,以便在实际开发中编写出更易于维护和理解的代码。


1. 使用逻辑运算符进行安全的参数检查

在这里插入图片描述

在 JavaScript 中,逻辑运算符常用于进行参数检查,以确保参数的类型和有效性。例如:

functionsafePush(arr, value){var array = Array.isArray(arr)&& arr ||[];
    array.push(value);return array;}
safePush

函数利用

&&

||

运算符来确保输入的

arr

是一个数组。如果

arr

不是数组,则使用空数组作为默认值,从而避免传入无效参数导致程序崩溃的风险。


2. 简化代码逻辑

在这里插入图片描述

逻辑运算符可以用于简化代码逻辑,使其更加简洁明了。例如:

var isValid = condition1 && condition2 || defaultValue;

这种写法可以减少

if...else

语句的使用,使代码更为精练。但在使用这种简化写法时,必须理解运算符的优先级和短路求值规则,以避免逻辑错误。


3. 确保逻辑表达式易于理解

在这里插入图片描述

尽管逻辑运算符可以简化代码,但过度使用复合逻辑运算符可能导致代码的可读性降低。因此,推荐对复杂逻辑进行注释说明,或者将逻辑拆分为多个步骤以提高可读性。

例如,将原代码拆分为易于理解的步骤:

var isArray = Array.isArray(arguments[0]);var arr = isArray ? arguments[0]:[];

这种写法虽然稍显冗长,但逻辑清晰,易于维护。


4. 结合空值合并运算符

??

在这里插入图片描述

JavaScript 中的新特性空值合并运算符

??

可以与逻辑运算符结合使用,进一步提高代码的可读性。例如:

var arr = Array.isArray(arguments[0])? arguments[0]:[];var finalArr = arr ??[];

空值合并运算符使得当

arr

null

undefined

时,可以自动提供一个默认值,从而使代码更加健壮。


💯JavaScript 运算符优先级表

在这里插入图片描述

为了更好地理解逻辑运算符的优先级,以下列出了 JavaScript 中部分常用运算符的优先级(从高到低):
优先级等级描述示例符号1成员访问、数组下标、函数调用

.

,

[]

,

()

2一元运算符

!

,

typeof

, 等3乘除、加减

*

,

/

,

+

,

-

4比较运算符

<

,

<=

,

>

,

>=

5相等运算符

==

,

===

,

!=

,

!==

6逻辑与

&&

7逻辑或`8空值合并

??

通过掌握这些运算符的优先级,可以更好地理解复杂表达式的计算顺序,从而编写出更为健壮的代码。


💯 拓展:短路求值的应用场景

在这里插入图片描述


1. 条件赋值

在这里插入图片描述

短路求值常用于条件赋值。例如:

var name = user && user.name ||'Guest';

此段代码用于从

user

对象中获取

name

属性,如果

user

user.name

null

undefined

,则返回默认值

'Guest'

。这种写法简洁明了。


2. 条件执行函数

在这里插入图片描述

短路求值还可以用于根据条件执行函数,例如:

isLoggedIn &&showDashboard();

当且仅当

isLoggedIn

true

时,

showDashboard()

函数才会被调用。如果

isLoggedIn

false

,则不会执行任何操作。这种方式可以有效减少冗余的

if

判断。


3. 防止空引用

在这里插入图片描述

在操作嵌套对象的属性时,短路求值可以防止出现空引用错误。例如:

var street = user && user.address && user.address.street;

这种写法确保了只有在

user

user.address

都存在的情况下,才会访问

user.address.street

,否则返回

undefined

。这种方式可以有效避免嵌套对象引用时的潜在错误。


4. 与默认参数结合

在这里插入图片描述

短路求值还可以用于结合函数的默认参数使用。例如:

functiongetConfig(config){var finalConfig = config ||{ theme:'dark', layout:'grid'};return finalConfig;}

如果未提供

config

参数,或者参数值为

null

undefined

,则使用默认配置对象。这种方式能够确保函数的行为一致性,并且提高代码的可维护性。


💯小结

  • 在这里插入图片描述 在 JavaScript 中,逻辑运算符 &&|| 的组合使用具有极大的灵活性和表达力。理解它们的优先级与短路求值机制是编写高质量代码的关键。在本文中,我们通过示例代码详细分析了逻辑运算符的执行过程,并讨论了它们的最佳实践。
  • 逻辑与 (&&) 的优先级高于逻辑或 (||) ,因此在复杂表达式中需要特别注意运算符的执行顺序。
  • 短路求值特性 可以帮助简化代码逻辑,但在使用时必须小心,避免逻辑上的误解。
  • 在实际编写代码时,利用逻辑运算符简化参数检查和条件赋值操作时,应始终确保代码的可读性和可维护性。
  • 结合空值合并运算符 以及其他新特性可以进一步提升代码的健壮性和灵活性。

在这里插入图片描述



本文转载自: https://blog.csdn.net/2201_75539691/article/details/143981668
版权归原作者 小ᶻ☡꙳ᵃⁱᵍᶜ꙳ 所有, 如有侵权,请联系我们删除。

“【前端】深入理解 JavaScript 逻辑运算符的优先级与短路求值机制”的评论:

还没有评论