js操作符
运算符
JavaScript 中的运算符用于执行各种运算,包括数学运算、字符串连接、逻辑运算等。以下是 JavaScript 中常见的运算符分类及其具体介绍:
算术运算符
+:加法。用于数字相加或字符串连接。-:减法。*:乘法。/:除法。%:取余(模运算),返回两数相除的余数。++:自增运算符,将变量的值增加 1。可以是前自增(++x)或后自增(x++)。--:自减运算符,将变量的值减少 1。可以是前自减(--x)或后自减(x--)。
1 | var one = 0.1 |
1 | var x = 1 |
1 | var x = 0; |
++
在 JavaScript 中,++ 运算符用于将变量的值增加 1。它有两种形式:前置递增(++x)和后置递增(x++),这两种形式在某些情况下会有不同的行为。
前置递增(++x)
- 含义:先将变量
x的值增加 1,然后返回增加后的值。 - 示例: 在这个例子中,
1
2
3
4let x = 5;
let y = ++x;
console.log(x); // 输出 6
console.log(y); // 输出 6x先被增加 1,变为 6,然后y被赋值为 6。
后置递增(x++)
- 含义:先返回变量
x的当前值,然后将x的值增加 1。 - 示例: 在这个例子中,
1
2
3
4let x = 5;
let y = x++;
console.log(x); // 输出 6
console.log(y); // 输出 5y先被赋值为x的当前值 5,然后x的值被增加 1,变为 6。
使用场景
- 循环计数:在
for循环等场景中,++运算符常用于更新循环变量。这里1
2
3for (let i = 0; i < 10; i++) {
console.log(i);
}i++用于在每次循环后将i的值增加 1。 - 数组遍历:在遍历数组时,也可以使用
++运算符来更新索引。使用前置递增1
2
3
4let arr = [1, 2, 3, 4, 5];
for (let i = 0; i < arr.length; ++i) {
console.log(arr[i]);
}++i或后置递增i++在这种场景下效果相同,但前置递增在某些情况下可能有轻微的性能优势,因为不需要先返回原始值再进行递增操作。
注意事项
- 避免滥用:虽然
++运算符很简洁,但在一些复杂表达式中过度使用可能会导致代码难以理解。例如,尽量避免在一行代码中对同一个变量进行多次递增操作。这种代码很难一眼看出1
2
3// 不推荐
let x = 0;
let y = ++x + x++ + ++x;y的值是多少。 - 与其他运算符结合时要小心:当
++运算符与其他运算符结合使用时,要特别注意运算符的优先级和执行顺序。总之,1
2let x = 5;
let y = 2 * ++x; // 先将 x 增加 1,变为 6,然后计算 2 * 6,结果为 12++运算符在 JavaScript 中是一个非常实用的工具,但在使用时要注意其前置和后置形式的区别以及在复杂表达式中的使用规范,以确保代码的可读性和正确性。
赋值运算符
=:简单赋值。+=:加法赋值。等价于x = x + y。-=:减法赋值。等价于x = x - y。*=:乘法赋值。等价于x = x * y。/=:除法赋值。等价于x = x / y。%=:取余赋值。等价于x = x % y。**=:指数赋值。等价于x = x ** y。
赋值语句右侧的表达式含有关系运算符、逻辑运算符,其运算符的优先级是:关系运算符>逻辑运算符(先&&后||)。
1 | var a = 4 >= 6 || true && 1 || false; |
比较运算符
==:等于。进行类型转换后再比较值是否相等。===:严格等于。比较值和类型是否都相等。!=:不等于。进行类型转换后再比较值是否不相等。!==:严格不等于。比较值和类型是否都不相等。>:大于。<:小于。>=:大于等于。<=:小于等于.
逻辑运算符
&&:逻辑与。如果第一个操作数为真,则返回第二个操作数的值;否则返回第一个操作数的值。||:逻辑或。如果第一个操作数为假,则返回第二个操作数的值;否则返回第一个操作数的值。!:逻辑非。返回操作数的布尔值的反值。
位运算符
&:按位与。|:按位或。^:按位异或。~:按位非。<<:左移。>>:右移(带符号)。>>>:无符号右移。
字符串运算符
+:字符串连接。用于将两个或多个字符串连接在一起。
条件运算符(三元运算符)
? ::条件运算符。根据条件表达式的真假来选择两个表达式中的一个进行求值。格式为condition ? exprIfTrue : exprIfFalse。
类型运算符
typeof:返回一个值的数据类型。可能的返回值有"undefined"、"object"、"boolean"、"number"、"bigint"、"string"、"symbol"、"function"。instanceof:用于检测构造函数的原型是否出现在对象的原型链中。
解构赋值运算符
=:用于数组或对象的解构赋值。例如:1
2let [a, b] = [1, 2]; // 数组解构
let { x, y } = { x: 1, y: 2 }; // 对象解构
空值合并运算符
??:返回左侧表达式的结果,如果左侧表达式为null或undefined,则返回右侧表达式的结果。
可选链运算符
?.:用于访问对象的属性或调用方法,如果对象为null或undefined,则不会抛出错误,而是返回undefined。
空值合并赋值运算符
??=:如果左侧变量的值为null或undefined,则将其设置为右侧表达式的值。
链式赋值运算符
=:可以用于链式赋值,例如:这些运算符在 JavaScript 编程中非常常用,掌握它们的使用对于编写高效、清晰的代码非常重要。1
2let a, b, c;
a = b = c = 3; // a、b、c的值都为3
几个问号运算符
1 | var a = "aaa",obj = {a:1},k; |
减法的误差
在 JavaScript 中进行小数相减时,常常会遇到精度问题,这是因为 JavaScript 中的浮点数是按照 IEEE 754 标准存储的,无法精确表示某些小数,从而导致计算结果出现误差。例如:
1 | console.log(0.1 - 0.2); // 输出 -0.10000000000000003 |
为了解决这个问题,可以采用以下几种方法:
1. 使用 toFixed 方法
toFixed 方法可以将数字格式化为指定小数位数的字符串,然后可以将其转换为数字类型。这种方法适用于对结果精度要求不是极高的情况。
1 | const result = Number((0.1 - 0.2).toFixed(10)); |
这里 toFixed(10) 表示保留 10 位小数,可以根据实际需要调整小数位数。需要注意的是,toFixed 方法返回的是字符串,所以需要用 Number 函数将其转换为数字。
2. 使用乘除法转换为整数计算
先将小数乘以一个适当的倍数转换为整数,进行整数相减后再除以相同的倍数还原为小数。这种方法可以避免浮点数运算的精度问题。
1 | function subtract(num1, num2) { |
在这个例子中,通过计算两个小数的小数位数,确定乘以的倍数,然后进行整数运算,最后还原为小数。这种方法可以精确地进行小数相减运算。
3. 使用第三方库
有一些第三方库如 decimal.js、bignumber.js 等专门用于处理高精度的数值运算,它们可以很好地解决 JavaScript 中浮点数运算的精度问题。
以 decimal.js 为例:
1 | const Decimal = require('decimal.js'); |
使用第三方库可以方便地进行各种高精度的数值运算,但会增加项目的依赖和体积。
4. 使用 Math. round 方法结合适当的倍数
这种方法与第二种方法类似,但在进行乘除法转换时,使用 Math.round 方法对结果进行四舍五入,以减少精度误差。
1 | function subtract(num1, num2) { |
这里选择了 10 的 10 次方作为倍数,可以根据实际精度要求调整倍数的大小。这种方法简单易实现,也能在一定程度上解决精度问题。
delete
在 JavaScript 中,delete 运算符用于从对象中删除一个属性。如果删除成功,delete 运算符会返回 true;如果删除失败(例如属性不存在或属性是不可配置的),则返回 false。
1. 基本用法
delete 运算符的基本语法如下:
1 | delete object.property; |
示例:
1 | const obj = { a: 1, b: 2, c: 3 }; |
2. 返回值
- 如果属性被成功删除,
delete返回true。 - 如果属性不存在,
delete也会返回true。 - 如果属性是不可配置的(即设置了
configurable: false),delete将返回false。
示例:
1 | const obj = { a: 1 }; |
3. 删除数组元素
虽然 delete 可以删除数组中的元素,但它不会改变数组的长度,也不会移动后续的元素。被删除的元素会变成 undefined。
示例:
1 | const arr = [1, 2, 3, 4]; |
注意:如果需要从数组中移除元素,建议使用数组方法(如 splice 或 filter),而不是 delete。
4. 删除对象的原型属性
delete 只能删除对象自身的属性,而不能删除继承自原型链的属性。如果需要删除原型链上的属性,可以使用 delete 与 Object.getPrototypeOf 结合。
示例:
1 | const obj = { a: 1 }; |
5. 注意事项
- 不可配置属性:如果属性的
configurable属性为false,则无法使用delete删除该属性。 - 严格模式:在严格模式下,删除不可配置属性会抛出错误,而不是返回
false。 - 数组索引:删除数组元素时,
delete不会改变数组的长度,也不会移动后续元素。
示例(严格模式):
1 | ; |
6. 总结
delete 运算符用于从对象中删除属性,但需要注意以下几点:
- 它只能删除对象自身的属性,不能删除继承自原型链的属性。
- 如果属性是不可配置的,
delete将返回false或抛出错误(严格模式)。 - 在删除数组元素时,建议使用数组方法(如
splice或filter),而不是delete,因为delete不会改变数组的长度。
合理使用delete可以帮助你动态地管理对象的属性,但在使用时需要清楚它的行为和限制。