• 02 【JS表达式与操作符】


    2.JS表达式与操作符

    什么是表达式和运算符?

    表达式:由 操作数 和 运算符 组成的式子。

    表达式的分类:算术、关系、逻辑、赋值、综合。

    2.1 算术表达式

    2.1.1 算术运算符

    意义运算符
    +
    -
    *
    /
    取余%

    推荐一律使用 () 来强制规定优先级!

    + 有 “加法” 和 “连字符” 两种作用,如果 + 的某一边是字符串那么就为 ”连字符“,否则为 ”加法“。

    2.1.2 隐式类型转换

    如果参与数学运算的某操作数不是数字类型,那么 JS 会自动将此操作数转换为数字型。

     3 * '4';        // 12
     true + true;    // 2
     false + 2;      // 2
     3 * '2天';      // NaN
     "z" * "j";      // NaN
     3 + '2天';      // '32天'
     3 + null;       // 0
     3 * '';         // 0
     3 * ' ';        // 0
     3 + '';         // '3'
     3 + ' ';        // '3 '
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    隐式转换的本质是 JS 内部自动调用 Number() 函数

    2.1.3 有关IEEE754

    在 JS 中,有些小数的数学运算不是很精准。

     0.1 + 0.2;  // 0.30000000000000004
    
    • 1

    JS 使用了 IEEE754 二进制浮点数算术标准,这会使一些个别的小数运算产生 “丢失精度” 问题。

    注意:不是所有的小数运算都会出现精度问题,只是少数部分。

    几乎所有的高级语言都使用了 IEEE754 二进制浮点数算术标准。

    IEEE754 二进制浮点数算术标准是计算机底层编译标准,了解即可!

    【解决办法】

    在进行小数运算时,要调用数字的 toFixed() 方法保留指定的小数位数。

    toFixed() 括号内接受一个保留小数位数的参数。

     (0.1 + 0.2).toFixed(2);             // '0.30',默认得到一个字符串值
     Number((0.1 + 0.2).toFixed(2));      // 0.3
    
    • 1
    • 2

    toFixed() 遵循 “四舍五入” 原则。

     (0.9945).toFixed(3);    // "0.995"
    
    • 1

    最后要注意浮点数的相等比较:

     1 / 3 === (1 - 2 / 3); // false
    
    • 1

    这不是 JavaScript 的设计缺陷。浮点数在运算过程中会产生误差,因为计算机无法精确表示无限循环小数。要比较两个浮点数是否相等,只能计算它们之差的绝对值,看是否小于某个阈值:

     Math.abs(1 / 3 - (1 - 2 / 3)) < 0.0000001; // true
    
    • 1

    还有一种解决技巧,就是将浮点数转换为整数进行计算:

     0.1 + 0.2;  // 0.30000000000000004
     (0.1 * 10 + 0.2 * 10) / 10; // 0.3
    
    • 1
    • 2

    2.1.4 幂和开根号

    JS 中没有提供幂运算、开根号的运算符,需要使用 Math 对象的相关方法进行计算。

    Math.pow(a, b):求 a 的 b 次方。

    Math.sqrt(a):求 a 的平方根。

     Math.pow(2, 3);     // 8
     Math.pow(3, 2);     // 9
     Math.sqrt(81);      // 9
     Math.sqrt(-81);     // NaN
    
    • 1
    • 2
    • 3
    • 4

    2.1.5 向上取整和向下取整

    Math.ceil():向上取整。

    Math.floor():向下取整。

    Math.round():把一个数字舍入为最接近的整数(“四舍六入”,“五不一定”)

    注意:向上、向下的标准是:X轴正方向为上!

    负 ———— 0 ————> 正

    Math.ceil(2.4);			// 3
    Math.floor(2.4);		// 2
    
    Math.ceil(-2.4);		// -2
    Math.floor(-2.4);		// -3
    
    Math.ceil(2);			// 2
    Math.floor(2);			// 2		
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2.2 关系表达式

    2.2.1 关系运算符

    意义运算符
    大于>
    小于<
    大于或等于>=
    小于或等于<=
    等于==
    不等于!=
    全等于===
    不全等于!==

    2.2.2 相等和全等

    两个等号 == 运算符,不考虑值的类型,它会进行隐式转换后比较值的字面量是否相等。

    三个等号 === 运算符,不仅比较值是否相同,也比较类型是否相同。

    5 == '5';		// true
    5 === '5';		// false
    1 == true;			// true
    1 === true;			// false
    
    0 == false;			// true
    0 === false; 		// false
    
    0 == undefined;		// false
    0 === undefined;	// false
    
    undefined == null;	// true
    undefined === null;	// false
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    null 和 undefined 用 == 进行比较涉及隐式强制类型转换,ES5 规范中规定。

    === 比较为 false,是因为 null 与 undefined 类型不同。

    建议没有特殊情况请一律使用 ===

    2.2.3 NaN不自等

    NaN 作为一个特殊的数字类型值,它在用 == 比较的时候也有特殊的结果。

    NaN == NaN;			// false
    NaN	=== NaN;		// false
    
    • 1
    • 2

    【如何判断某变量值为 NaN】

    isNaN() 函数可以用来判断变量值是否为 NaN。

    isNaN(NaN);		// true
    isNaN(5);		// false
    isNaN("5");		// false
    
    • 1
    • 2
    • 3

    但 isNaN() 也不好用,它的机理是:只要该变量传入 Number() 的执行结果是 NaN,则 isNaN() 函数都会得到 true。

    对于,undefined 和 null,这种情况一般来说需要先进行单独判断,再进行 isNaN 判断。

    isNaN(undefined);	// true
    isNaN('3天');	   // true
    isNaN(null);		// false
    
    • 1
    • 2
    • 3

    2.2.4 JS中没有连比

    例如:3 <= a <= 15 的写法是错误的,应该为:a >= 3 && a <= 15

    2.3 逻辑表达式

    2.3.1 逻辑运算符

    意义运算符
    !
    &&
    `

    2.3.2 非运算

    ! 表示 “非”,也可以称为 “置反运算”。

    ! 是一个 “单目运算符”,只需要一个操作数。

    置反运算的结果一定是布尔值。

    !true;			// false
    !false;			// true
    !0;				// true
    !undefined;		// true
    !'';			// true
    !' ';			// false
    !null;			// true
    !'imooc';		// false
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    !! 常用于确定一个值的布尔属性。

    !!true;		// true
    !!0;		// false
    !!'';		// false
    !!' ';		// true
    !!'imooc';	// true
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2.3.3 与运算

    && 是 “双目运算符”。

    核心:全真为真、有假即假

    2.3.4 或运算

    || 是 “双目运算符”。

    核心:全假为假、有真即真

    2.3.5 短路运算

    &&||,都属于 “短路运算符”。

    (1)&& 短路运算

    由于 && 运算的核心是:“全真为真、有假即假”,所以:

    • 如果 a && ba 为真,那么该表达式的值由 b 决定(计算 a 又计算 b)
    • 如果 a && ba 为假,那么该表达式的值由 a 决定(只计算 a)
    3 && 6;				// 6
    undefined && 15;	// undefined
    15 && undefined;	// undefined
    null && 2;			// null
    '' && 16;			// ''
    NaN && undefined;	// NaN
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    (2)|| 短路运算

    由于 || 运算的核心是:“全假为假、有真即真”,所以:

    • 如果 a || ba 为真,那么该表达式的值由 a 决定(只计算 a)
    • 如果 a || ba 为假,那么该表达式的值由 b 决定(计算 a 又计算 b)
    3 || 6;				// 3
    0 || 6;				// 6
    null || undefined;	// undefined
    'a' || 'b';			// 'a'
    NaN || null;		// null
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2.3.6 逻辑运算的优先级

    优先级:! > && > ||

    !true || true;		// true
    3 && 4 || 5 && 6// 4
    
    • 1
    • 2

    推荐使用 () 来规定优先级。

    2.4 赋值表达式

    2.4.1 赋值运算符

    意义运算符
    赋值=
    快捷赋值+=-=*=/=%=
    自增运算++
    自减运算--

    2.4.2 赋值运算产生值

    赋值运算也产生值,等号后面的值将作为 “赋值运算的值”。

    var a;
    console.log(a = 4);		// 4
    
    • 1
    • 2

    这就意味着,可以连续使用赋值运算符。

    var a, b, c;
    a = b = c = 15;
    console.log(a);		// 15
    console.log(b);		// 15
    console.log(c); 	// 15
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在实际开发中不建议使用连续赋值!

    2.4.3 自增自减运算

    a++:先用再加;++a:先加再用。

    自增可以使变量在原值的基础上自增1
    自增使用 ++
    自增可以使用 前++(++a)后++(a++)
    无论是++a 还是 a++都会立即使原变量自增1
    不同的是++a和a++的值是不同的,
    ++a的值是变量的新值(自增后的值)
    a++的值是变量的原值(自增前的值)

    a--:先用再减;--a:先减再用。

    自减可以使变量在原值的基础上自减1
    自减使用
    自减可以使用 前(a)后(a)
    无论是a 还是 a都会立即使原变量自减1
    不同的是a和a的值是不同的,
    a的值是变量的新值(自减后的值)
    a的值是变量的原值(自减前的值)

    2.5 三元运算符

    条件表达式 ? 表达式1 : 表达式2;

    当条件表达式为真时执行表达式1并返回结果,否则执行表达式2并返回结果。

    【三元运算符的用途】

    根据某个条件是否成立,在两个不同值中选择变量的值。

    var age = 24;
    var type = age >= 18 ? '成年人' : '未成年人';
    alert(type);
    
    • 1
    • 2
    • 3

    2.6 综合运算的运算顺序

    和数学中一样,JS中的运算符也是具有优先级的,
    比如 先乘除 后加减 先与 后或
    具体的优先级可以参考优先级的表格,在表格中越靠上的优先级越高,
    优先级越高的越优先计算,优先级相同的,从左往右计算。

    非运算 > 数学运算 > 关系运算 > 逻辑运算

    优先级不需要记忆,如果越到拿不准的,使用()来改变优先级。

  • 相关阅读:
    Mybiosource丨Mybiosource月桂碱,抑制剂说明书
    数据降维(Data Dimensionality Reduction)
    Python —— pytest框架
    安全狗助力厦门“单一窗口”开展网络安全应急演练
    CS231n-2022 Module1: 神经网络3:Learning and Evaluation
    【MySql】mysql之基础语句
    vue——基于element嵌套表格+多选
    .NET性能优化-复用StringBuilder
    到底什么是“算力网络”?
    抖音短视频实操:矩阵号之为什么要做矩阵号和如何做矩阵号(下)
  • 原文地址:https://blog.csdn.net/DSelegent/article/details/126325616