学过编程语言的都知道一种大部分编程语言其实都存在许多相似的地方,比如数学中的四则运算,这个在JS中同样生效,不过在JS中,有进行部分拓展,这个也是其他语言中都有的,每个语言都有其功能和特性,JS也不例外。下面我们就来看看JS中的运算符的种类和相关介绍吧:
运算符:我们通常也被称作为操作符,用于实现赋值,比较和执行,行算数运算等功能的符号。
表达式:由数字、运算符 、变量等组成的式子,我们称作表达式,例如 1 + 1;
算术运算符
关于算术运算符这个咱们经常见到了,已经是见怪不怪了,在JS中有以下算术运算符:
加法(+):用于将两个值相加。
减法(-):用于将一个值减去另一个值。
乘法(*):用于将两个值相乘。
除法(/):用于将一个值除以另一个值。
取余(%):用于获取两个值相除的余数。
自增(++):用于将变量的值增加1。自增运算符可以放在变量前(前缀自增)或变量后(后缀自增)。
自减(--): 用于将变量的值减1。自减运算符可以放在变量前(前缀自减)或变量后(后缀自减)。
let x = 5;
let y = ++x; // 前缀自增,x先加1,然后赋值给y,x和y的值都为6 使用口诀 : 先自加 1 再返回值
let z = x++; // 后缀自增,x的值先赋值给z,然后x再加1,z为6,x为7 使用口诀 : 先返回原值 后自加
console.log(1 + 1);// 取余 %console.log((4 % 2));// 0console.log((3 % 5));// 3console.log("2%7 = "+(2%7)); // 2// 浮点数 算数里面会有问题console.log(0.1 + 0.2 ); console.log(0.1 * 0.2 ); // 我们不能拿着浮点数来进行 相比较是否相等var num = 0.1 + 0.2;console.log(num == 0.3); // false// 如何判断一个数能被整除: 它的余数为0 说明这个数能被 整除 这就是 % 取余运算符的主要用途// 算术运算先后 和数学上一致
使用算术运算符会碰到的问题
- 数值溢出:当进行算术运算时,如果结果超出了JavaScript数值的表示范围,可能会导致数值溢出。这通常发生在处理非常大或非常小的数值时。要避免数值溢出,可以使用BigInt类型来处理大整数,或者进行适当的范围检查和处理。
var result= 0.1 + 0.2; // 结果不是0.3 而是 0.30000000000000004
var result= 0.1 * 0.2; // 结果不是0.02 而是 0.020000000000000004
-
浮点数精度问题:由于JavaScript中的数字类型是基于浮点数的,因此在进行浮点数运算时可能会出现精度问题。这是由于浮点数的二进制表示无法精确地表示某些十进制数。例如,0.1 + 0.2 的结果可能不是预期的0.3,而是一个近似值。为了避免浮点数精度问题,可以使用适当的舍入函数或将浮点数转换为整数进行计算。
-
除以零:在进行除法运算时,如果除数为零,将会导致除以零的错误。这将引发一个异常,并可能导致程序中断。因此,在进行除法运算之前,应该确保除数不为零。
-
字符串拼接:在使用加法运算符(+)时,如果其中一个操作数是字符串,JavaScript会将其视为字符串拼接操作,而不是数值相加。这可能导致意外的结果。要确保正确的数值相加,可以使用括号或将操作数转换为数值类型。
-
运算顺序:在复杂的表达式中,运算符的优先级和结合性可能会导致意外的结果。要确保表达式按预期进行计算,可以使用括号来明确指定运算的顺序。
赋值运算符:用于将值赋给变量。
简单赋值(=):用于将一个值赋给一个变量。
加法赋值(+=):用于将一个值加到变量上,并将结果赋给该变量。
减法赋值(-=):用于将一个值从变量中减去,并将结果赋给该变量。
乘法赋值(*=):用于将一个值乘以变量,并将结果赋给该变量。
除法赋值(/=):用于将变量的值除以一个值,并将结果赋给该变量。
取余赋值(%=):用于将变量的值除以一个值的余数,并将结果赋给该变量。
左移赋值:<<= : 将变量的位向左移动指定的位数,并将结果赋值给变量。
右移赋值:>>= : 将变量的位向右移动指定的位数,并将结果赋值给变量。右移操作会保留符号位。
无符号右移赋值:>>>= :将变量的位向右移动指定的位数,并将结果赋值给变量。无符号右移操作不保留符号位,用0填充左侧空位。
按位与赋值:&= :对变量的每个位执行按位与操作,并将结果赋值给变量。
按位或赋值:|= :对变量的每个位执行按位或操作,并将结果赋值给变量。
按位异或赋值:^= :对变量的每个位执行按位异或操作,并将结果赋值给变量。
let x = 5; // 二进制表示为 00000101x <<= 2; // 左移2位,结果为 00010100,即20console.log(x); // 输出为 20let x = -10; // 二进制表示为 11111111111111111111111111110110x >>= 2; // 右移2位,结果为 11111111111111111111111111111101,即-3console.log(x); // 输出为 -3let x = -10; // 二进制表示为 11111111111111111111111111110110x >>>= 2; // 无符号右移2位,结果为 00111111111111111111111111111101,即1073741821console.log(x); // 输出为 1073741821let x = 12; // 二进制表示为 00001100x &= 5; // 按位与操作,结果为 00000100,即4console.log(x); // 输出为 4let x = 12; // 二进制表示为 00001100x |= 5; // 按位或操作,结果为 00001101,即13console.log(x); // 输出为 13let x = 12; // 二进制表示为 00001100x ^= 5; // 按位异或操作,结果为 00000101,即5console.log(x); // 输出为 5
比较运算符:用于比较两个值,并返回布尔值。
相等(==):用于比较两个值是否相等。
不相等(!=):用于比较两个值是否不相等。
全等(===):用于比较两个值的值和类型是否完全相等。
不全等(!==):用于比较两个值的值和类型是否不完全相等。
大于(>):用于检查一个值是否大于另一个值。
小于(<):用于检查一个值是否小于另一个值。
大于等于(>=):用于检查一个值是否大于或等于另一个值。
小于等于(<=):用于检查一个值是否小于或等于另一个值。
逻辑运算符:用于组合和操作布尔值。
逻辑与(&&):用于检查两个条件是否同时为真。
逻辑或(||):用于检查两个条件是否至少有一个为真。
逻辑非(!):用于取反一个条件的值。
位运算符:用于对二进制位进行操作。
- 按位与(&):对两个操作数的每个位执行逻辑与操作。如果两个操作数的对应位都为1,则结果为1;否则,结果为0。使用情况:按位与操作常用于位掩码、清除特定位、提取特定位等操作。
- 位或(|):对两个操作数的每个位执行逻辑或操作。如果两个操作数的对应位至少有一个为1,则结果为1;否则,结果为0。使用情况:按位或操作常用于设置特定位、合并标志等操作。
- 按位异或(^):对两个操作数的每个位执行逻辑异或操作。如果两个操作数的对应位不相同,则结果为1;否则,结果为0。使用情况:按位异或操作常用于交换变量值、加密解密、校验等操作。
- 按位非(~):对操作数的每个位执行逻辑非操作,将0变为1,将1变为0。按位非操作是一元操作符,只作用于一个操作数。使用情况:按位非操作常用于取反操作、位级别的数据处理等。
- 左移(<<):将操作数的位向左移动指定的位数。左移操作会在右侧填充0。使用情况:左移操作常用于位级别的数据处理、乘以2的幂等操作等。
- 右移(>>):将操作数的位向右移动指定的位数,保留符号位。右移操作会在左侧填充符号位的值。使用情况:右移操作常用于位级别的数据处理、除以2的幂等操作等。
- 无符号右移(>>>):将操作数的位向右移动指定的位数,不保留符号位。无符号右移操作会在左侧填充0。使用情况:无符号右移操作常用于位级别的数据处理、无符号数值的处理等。
let x = 5; // 二进制表示为 00000101let y = 3; // 二进制表示为 00000011let result = x & y; // 按位与操作,结果为 00000001,即1console.log(result); // 输出为 1let x = 5; // 二进制表示为 00000101let y = 3; // 二进制表示为 00000011let result = x | y; // 按位或操作,结果为 00000111,即7console.log(result); // 输出为 7let x = 5; // 二进制表示为 00000101let y = 3; // 二进制表示为 00000011let result = x ^ y; // 按位异或操作,结果为 00000110,即6console.log(result); // 输出为 6let x = 5; // 二进制表示为 00000101let result = ~x; // 按位非操作,结果为 11111010,即-6console.log(result); // 输出为 -6let x = 5; // 二进制表示为 00000101let result = x << 2; // 左移2位,结果为 00010100,即20console.log(result); // 输出为 20let x = -10; // 二进制表示为 11111111111111111111111111110110let result = x >> 2; // 右移2位,结果为 11111111111111111111111111111101,即-3console.log(result); // 输出为 -3let x = -10; // 二进制表示为 11111111111111111111111111110110let result = x >>> 2; // 无符号右移2位,结果为 00111111111111111111111111111101,即1073741821console.log(result); // 输出为 1073741821
三元运算符:也称为条件运算符,根据条件选择不同的值。
条件 ? 结果1 : 结果2
条件:一个可以求值为布尔类型的表达式,用于判断条件的真假。
结果1:如果条件为真,则返回的值。
结果2:如果条件为假,则返回的值。
let age = 18;
let message = (age >= 18) ? "成年人" : "未成年人";
console.log(message); // 输出为 "成年人"
typeof 运算符:用于检测操作数的数据类型。
typeof 操作数
typeof 42; // "number"
typeof "Hello"; // "string"
typeof true; // "boolean"
typeof undefined; // "undefined"
typeof null; // "object" (这是一个历史遗留问题,实际上 null 是一个原始值)
typeof []; // "object"
typeof {}; // "object"
typeof function() {}; // "function"
typeof 运算符用于检测不同类型的操作数。它返回的字符串表示操作数的数据类型。例如,typeof 42 返回的是字符串 “number”,表示操作数是一个数字类型。
需要注意的是,typeof null 返回的是 “object”,这是一个历史遗留问题,实际上 null 是一个原始值。而对于数组和对象,typeof 运算符同样返回 “object”,无法区分它们的具体类型。如果需要更精确地检测对象的类型,可以使用其他方法,如 Array.isArray() 来检测数组,或者使用 instanceof 运算符来检测对象的构造函数。
instanceof 运算符:用于检测对象是否属于特定的类型。
对象 instanceof 类型
let str = "Hello";
console.log(str instanceof String); // falselet num = new Number(42);
console.log(num instanceof Number); // truelet arr = [1, 2, 3];
console.log(arr instanceof Array); // truelet obj = { name: "John" };
console.log(obj instanceof Object); // truefunction Person(name) {this.name = name;
}
let person = new Person("Alice");
console.log(person instanceof Person); // true
console.log(person instanceof Object); // true