找回密码
 立即注册
首页 业界区 业界 Web前端入门第 58 问:JavaScript 运算符 == 和 === 有 ...

Web前端入门第 58 问:JavaScript 运算符 == 和 === 有什么区别?

龙正平 5 天前
运算符

JavaScript 运算符是真的多,尤其是 ES6 之后还在不停的加运算符,其他编程语言看 JS 就像怪物一样,各种骚操作不断~~
运算符分类

1、算术运算符
算术运算符的作用就是用来基础计算,跟小学课本一样,包含:加 +,减 -,乘 *,除 /,取余(也叫做取模) %,指数 **,自增 ++,自减 --。
只是需注意:乘号不再是 x,除号也不再是 ÷!
与我们学过的运算法则一样,乘法与除法优先级比加减法高,如果要改变优先级,需要使用括号 (),只是一个算式中有多个括号还是使用小括号,不用中括号而已。
  1. // 加法
  2. console.log(3 + 5); // 8
  3. console.log(3 + '5'); // '35'(字符串拼接)
  4. // 减法、乘法、除法
  5. console.log(10 - 3); // 7
  6. console.log(2 * 4); // 8
  7. console.log(10 / 2); // 5
  8. // 取余、指数
  9. console.log(10 % 3); // 1(余数)
  10. console.log(2 ** 3); // 8(2的3次方)
  11. // 自增/自减(注意前置与后置)
  12. let a = 5;
  13. console.log(a++); // 5(先返回原值,再自增)
  14. console.log(++a); // 7(先自增,再返回新值)
  15. // 使用括号改变优先级
  16. console.log((2 + 3) * 4); // 5 * 4 = 20
  17. console.log(((2 + 3) - (5 -3)) * 4); // (5 - 2) * 4 = 12
复制代码
2、比较运算符
一般用于逻辑比较,比如比较两个值是否相等,比较两个数的大小等等。包含:等于 ==,严格等于(全等于) ===,不等于 !=,严格不等于(不全等) !==,大于 >,小于 =,小于等于  2);    // trueconsole.log('apple' > 'banana');    // false(按字母顺序比较)console.log(2 >= 2);    // trueconsole.log(2 >>。
这部分运算符涉及到底层的二进制运算,如果有兴趣可以查找相关资料学习。
  1. // 松散比较(类型转换)
  2. console.log(5 == '5');    // true(值相等)
  3. console.log(0 == false);    // true(0和false在松散比较中等价)
  4. console.log(5 != '5');    // false(值相等)
  5. // 严格比较(值和类型)
  6. console.log(5 === '5');    // false(类型不同)
  7. console.log(0 === false);    // false(类型不同)
  8. console.log(5 !== '5');    // true(类型不同)
  9. // 其他比较
  10. console.log(3 > 2);    // true
  11. console.log('apple' > 'banana');    // false(按字母顺序比较)
  12. console.log(2 >= 2);    // true
  13. console.log(2 <= 2);    // true
复制代码
6、三元运算符
又称为三目运算符(吐槽下:乱七八糟的名字特多),一般用于简化 if else 语句,但不建议过多嵌套,要不然代码阅读起来费劲。
语法:condition ? expr1 : expr2。
  1. const a = 5;
  2. const b = '5';
  3. if (a + '' === '5') {} // 将 a 转换为字符串再比较
  4. if (b - 0 === 5) {} // 将 b 转换为数字再比较
复制代码
可以看看多次嵌套的代码是否是难以阅读,为了项目的可维护性,真心不建议把三元运算符用于多次嵌套。
7、特殊运算符
JS 内置的关键字,包含:typeof, instanceof, delete, void, in, new。
  1. // 逻辑与(&&):短路特性
  2. console.log(true && 'Hello');    // 'Hello'(返回最后一个真值)
  3. console.log(false && 'Hello');   // false(遇到假值直接返回)
  4. // 逻辑或(||):短路特性
  5. console.log(0 || 'default');     // 'default'(返回第一个真值)
  6. console.log('A' || 'B');         // 'A'
  7. // 逻辑非(!)
  8. console.log(!true);              // false
  9. console.log(!!'非空字符串');      // true(强制转布尔值)
  10. // 应用场景
  11. // 默认值设置
  12. function greet(name) {
  13.   name = name || 'Guest';      // 若 name 为假值,返回 'Guest'
  14.   console.log(`Hello, ${name}!`);
  15. }
  16. greet();                       // 'Hello, Guest!'
  17. // 条件执行函数
  18. true && console.log('执行了!'); // 输出 '执行了!'
  19. false || console.log('执行了!'); // 输出 '执行了!'
复制代码
8、ES6+ 运算符
ES6 之后新增的一些运算符,骚操作从这里开始。包含:展开运算符 ..., 可选链 ?., 空值合并 ??
  1. let x = 10;
  2. x += 5;   // x = x + 5 → 15
  3. x *= 2;   // x = 15 * 2 → 30
  4. x **= 2;  // x = 30^2 → 900
  5. console.log(x); // 900
复制代码
类型转换规则

当操作数类型不同时,JS 会按内部规则尝试进行类型转换:
  1. // 按位与(&)
  2. console.log(5 & 3);      // 1(二进制 101 & 011 → 001)
  3. // 按位或(|)
  4. console.log(5 | 3);      // 7(101 | 011 → 111)
  5. // 无符号右移(>>>)
  6. console.log(-1 >>> 0);   // 4294967295(将负数转为无符号整数)
复制代码
常见问题

1、== 和 === 的区别是什么?
答:== 会进行类型转换后比较,=== 严格比较值和类型。
2、逻辑运算符 && 和 || 的返回值是什么?
答:返回第一个决定表达式结果的子表达式值(短路求值)。
3、1 + '1' 和 '1' + 1 的结果是什么?
答:均为 '11'(字符串拼接)。
4、0 == false 和 '' == false 的结果是什么?为什么?
答:均为 true,因 == 会进行隐式转换。
5、typeof null 返回什么?为什么?
答:'object'(历史遗留问题)。
6、可选链 ?. 和空值合并 ?? 的作用是什么?
答:obj?.prop 避免访问 null/undefined,a ?? b 仅在 a 为 null/undefined 时返回 b。
7、以下代码的输出是什么?
  1. const age = 20;
  2. const canVote = age >= 18 ? 'Yes' : 'No';
  3. console.log(canVote); // 'Yes'
  4. // 等价于
  5. if (age >= 18) {
  6.   console.log('Yes');
  7. } else {
  8.   console.log('No');
  9. }
  10. // 三元运算符的多次嵌套
  11. const a = age > 80 ? '高龄老人' : (age > 60 ? '老年人' : (age > 40 ? '中年人' : '年轻人'))
复制代码
8、console.log(!!' ') 的输出是什么?
答:true(非空字符串转布尔值为 true)。
9、如何用短路求值简化代码?
  1. // typeof 返回变量的类型字符串
  2. console.log(typeof 42);          // 'number'
  3. console.log(typeof null);        // 'object'(历史遗留问题)
  4. // instanceof 检查对象是否是某个构造函数的实例(基于原型链)
  5. class Person {}
  6. const p = new Person();
  7. console.log(p instanceof Person); // true
  8. // delete 删除对象的属性或数组元素(对变量无效)
  9. const obj = { a: 1 };
  10. delete obj.a;                   // 删除属性
  11. console.log(obj.a);             // undefined
  12. // void 执行表达式并返回 undefined
  13. console.log(void (1 + 1));          // undefined
  14. // in 检查对象或其原型链中是否包含指定属性
  15. console.log('toString' in obj);     // true(继承自Object.prototype)
  16. // new 创建构造函数实例(调用构造函数,绑定 this)
  17. function Car(brand) {  
  18.   this.brand = brand;  
  19. }  
  20. const myCar = new Car('Tesla');  
  21. console.log(myCar.brand);           // 'Tesla'  
  22. /* 等价于以下过程:
  23. 1. 创建一个空对象 {}
  24. 2. 将空对象的原型指向 Car.prototype
  25. 3. 执行 Car 函数,this 指向该空对象
  26. 4. 返回新对象   */
复制代码
10、如何安全访问嵌套对象属性?
答:使用可选链 obj?.a?.b ?? 'default'。
写在最后

优先使用 === 和 !== 避免 JS 的隐式转换带来的不确定性。
隐式转换机制需特别注意,特别是在处理用户输入、API 接口响应数据时,稍不注意就掉坑了!!
如果您有大量计算工作量,那么必须啃书二进制的位运算符,否则使用十进制运算会拖慢程序运行速度。

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册