🚀 JavaScript 运算符的那些"坑"与技巧
➕ 加法运算符的神奇世界
javascript
console.log(1 + 2) // 3 - 数值相加
console.log(true + true) // 2 - 布尔值转数值
console.log('3' + 4 + 5) // "345" - 字符串拼接
console.log([] + 1) // "1" - 空数组转空字符串
console.log({} + 1) // "[object Object]1"
💡 记住:加法优先进行字符串拼接!
➖ 减法运算符:数值的天下
javascript
console.log('4' - '2') // 2 - 强制转数值
console.log('4' - true) // 3 - true转为1
console.log({} - 1) // NaN - 对象无法转数值
🎯 规律:减法、乘法、除法都会强制转为数值类型
🔢 自增自减:位置很重要
javascript
let i = 5;
console.log(++i); // 6 - 先自增再使用
console.log(i++); // 6 - 先使用再自增
⚠️ 最佳实践 :开发中建议统一使用 i++
避免混淆
⚖️ 比较运算符的陷阱
javascript
console.log(5 > '3') // true - '3'转为数值3
console.log(5 > NaN) // false - NaN比较永远false
console.log(5 < NaN) // false - 同上
console.log('b' > 'a') // true - 字符串按Unicode比较
🚨 重点:NaN 参与比较永远返回 false!
🎯 实用技巧
- 使用
+
快速转数值:+'123'
→123
- 指数运算:
2 ** 3
=8
- 取余特性:小数对大数取余直接返回小数
掌握这些运算符特性,让你的 JavaScript 代码更加得心应手!
#JavaScript #前端开发 #编程技巧
javascript
这个推文总结了你文档中的核心要点,用简洁的代码示例和要点说明,适合在技术社交平台分享。
acewanghaha: 不要基于我的文档了 你写一篇基于js运算符的博客
GitHub Copilot: # JavaScript 运算符完全指南:从基础到进阶
## 前言
运算符是 JavaScript 中最基础也是最重要的概念之一。它们决定了数据如何被操作和组合。掌握运算符的工作原理,特别是类型转换的规则,对于写出可靠的 JavaScript 代码至关重要。
## 1. 算术运算符
### 加法运算符 (+)
加法运算符是最特殊的算术运算符,因为它既可以进行数值运算,也可以进行字符串拼接:
````javascript
// 数值相加
console.log(2 + 3); // 5
console.log(2.5 + 1.5); // 4
// 字符串拼接
console.log('Hello ' + 'World'); // "Hello World"
console.log('The answer is ' + 42); // "The answer is 42"
// 混合类型
console.log(5 + '3'); // "53" (字符串拼接)
console.log('5' + 3); // "53" (字符串拼接)
console.log(true + 1); // 2 (布尔值转数字)
console.log([] + 1); // "1" (空数组转空字符串)
规则:如果任一操作数是字符串,则执行字符串拼接;否则执行数值相加。
其他算术运算符
减法、乘法、除法和取余运算符都会将操作数转换为数字:
javascript
// 减法
console.log('10' - '3'); // 7
console.log('10' - true); // 9 (true 转为 1)
console.log('abc' - 1); // NaN
// 乘法
console.log('3' * '4'); // 12
console.log('3' * true); // 3
// 除法
console.log('15' / '3'); // 5
console.log(15 / 0); // Infinity
// 取余
console.log(10 % 3); // 1
console.log('10' % '3'); // 1
console.log(7.5 % 2); // 1.5
指数运算符 (**)
ES2016 引入的指数运算符:
javascript
console.log(2 ** 3); // 8
console.log(3 ** 2); // 9
console.log(2 ** 0.5); // 1.4142135623730951 (平方根)
console.log((-2) ** 2); // 4
2. 自增和自减运算符
自增 (++
) 和自减 (--
) 运算符有前置和后置两种形式:
javascript
let a = 5;
let b = 5;
// 前置:先运算,再返回值
console.log(++a); // 6,a 变为 6
console.log(a); // 6
// 后置:先返回值,再运算
console.log(b++); // 5,返回原值
console.log(b); // 6,b 已变为 6
// 实际应用中的差异
let arr = [1, 2, 3];
let i = 0;
console.log(arr[i++]); // 1,使用 i=0,然后 i 变为 1
console.log(arr[++i]); // 3,i 先变为 2,然后使用 i=2
3. 比较运算符
数值比较
javascript
console.log(5 > 3); // true
console.log('5' > '3'); // true (字符串转数字)
console.log('5' > 3); // true (字符串转数字)
console.log(true > false); // true (转为 1 > 0)
字符串比较
当两个操作数都是字符串时,按 Unicode 码点顺序比较:
javascript
console.log('apple' > 'banana'); // false
console.log('A' > 'a'); // false (A=65, a=97)
console.log('10' > '2'); // false (字符串比较,'1' < '2')
console.log('10' > '9'); // false (字符串比较,'1' < '9')
NaN 的特殊性
javascript
console.log(NaN > 5); // false
console.log(NaN < 5); // false
console.log(NaN == NaN); // false
console.log(NaN === NaN); // false
console.log(Number.isNaN(NaN)); // true (正确的判断方法)
4. 相等运算符
严格相等 (===) vs 宽松相等 (==)
javascript
// 严格相等:类型和值都必须相同
console.log(5 === 5); // true
console.log(5 === '5'); // false
console.log(true === 1); // false
console.log(null === undefined); // false
// 宽松相等:允许类型转换
console.log(5 == '5'); // true
console.log(true == 1); // true
console.log(null == undefined); // true
console.log('' == false); // true
console.log(0 == false); // true
最佳实践 :优先使用严格相等运算符 (===
) 避免意外的类型转换。
5. 逻辑运算符
逻辑与 (&&) 和逻辑或 (||)
JavaScript 的逻辑运算符返回操作数之一,而不是布尔值:
javascript
// 逻辑与:返回第一个假值,或最后一个值
console.log(true && 'hello'); // "hello"
console.log(false && 'hello'); // false
console.log('' && 'hello'); // ""
console.log('a' && 'b' && 'c'); // "c"
// 逻辑或:返回第一个真值,或最后一个值
console.log(false || 'hello'); // "hello"
console.log('' || 'default'); // "default"
console.log('a' || 'b'); // "a"
console.log(null || undefined || 'fallback'); // "fallback"
// 实际应用:设置默认值
function greet(name) {
name = name || 'Anonymous';
console.log('Hello, ' + name);
}
空值合并运算符 (??)
ES2020 引入,只有在左侧为 null
或 undefined
时才返回右侧:
javascript
console.log(null ?? 'default'); // "default"
console.log(undefined ?? 'default'); // "default"
console.log(0 ?? 'default'); // 0
console.log('' ?? 'default'); // ""
console.log(false ?? 'default'); // false
// 对比 || 运算符
console.log(0 || 'default'); // "default"
console.log(0 ?? 'default'); // 0
6. 位运算符
虽然在日常开发中较少使用,但在某些场景下非常有用:
javascript
// 按位与 (&)
console.log(5 & 3); // 1 (101 & 011 = 001)
// 按位或 (|)
console.log(5 | 3); // 7 (101 | 011 = 111)
// 按位异或 (^)
console.log(5 ^ 3); // 6 (101 ^ 011 = 110)
// 左移 (<<)
console.log(5 << 1); // 10 (相当于乘以2)
// 右移 (>>)
console.log(10 >> 1); // 5 (相当于除以2向下取整)
// 实际应用:快速判断奇偶数
function isEven(n) {
return (n & 1) === 0;
}
console.log(isEven(4)); // true
console.log(isEven(5)); // false
7. 三元运算符
条件运算符提供了简洁的条件判断语法:
javascript
// 基本语法:condition ? value1 : value2
let age = 18;
let message = age >= 18 ? 'Adult' : 'Minor';
console.log(message); // "Adult"
// 嵌套使用
let score = 85;
let grade = score >= 90 ? 'A' :
score >= 80 ? 'B' :
score >= 70 ? 'C' : 'D';
console.log(grade); // "B"
// 函数中的应用
function getAbsoluteValue(n) {
return n >= 0 ? n : -n;
}
8. 运算符优先级
了解运算符优先级可以帮助我们写出更清晰的代码:
javascript
// 乘除优先于加减
console.log(2 + 3 * 4); // 14,不是 20
// 比较优先于逻辑
console.log(true || false && false); // true
// 使用括号明确优先级
console.log((2 + 3) * 4); // 20
console.log(true || (false && false)); // true
9. 类型转换陷阱
JavaScript 的自动类型转换有时会产生意外结果:
javascript
// 加法的类型转换
console.log([] + []); // "" (空字符串)
console.log([] + {}); // "[object Object]"
console.log({} + []); // 0 (在某些环境中)
// 比较的类型转换
console.log([] == 0); // true
console.log([] == !![]); // false
console.log([] == false); // true
// 避免陷阱的最佳实践
console.log(String([]) + String([])); // ""
console.log(Array.isArray([])); // true
console.log([] === []); // false (不同对象)
10. 实用技巧
快速类型转换
javascript
// 转换为数字
console.log(+'123'); // 123
console.log(+'123.45'); // 123.45
console.log(+true); // 1
console.log(+false); // 0
// 转换为字符串
console.log(123 + ''); // "123"
console.log(true + ''); // "true"
// 转换为布尔值
console.log(!!'hello'); // true
console.log(!!0); // false
console.log(!!''); // false
实用的位运算技巧
javascript
// 向下取整
console.log(~~3.14); // 3
console.log(3.14 | 0); // 3
// 交换变量(不推荐,可读性差)
let a = 5, b = 10;
a ^= b;
b ^= a;
a ^= b;
console.log(a, b); // 10, 5
// 检查是否为2的幂
function isPowerOfTwo(n) {
return n > 0 && (n & (n - 1)) === 0;
}
console.log(isPowerOfTwo(8)); // true
console.log(isPowerOfTwo(10)); // false
总结
JavaScript 运算符虽然看似简单,但其背后的类型转换规则相当复杂。掌握这些规则不仅能帮助我们避免常见的错误,还能写出更加优雅和高效的代码。
最佳实践建议:
- 优先使用严格相等运算符 (
===
) - 明确使用类型转换而不是依赖自动转换
- 使用括号明确运算优先级
- 避免过于复杂的位运算,除非确实需要
- 在团队开发中保持一致的编码风格
通过深入理解运算符的工作原理,我们可以写出更加可靠和可维护的 JavaScript 代码。