深度剖析之由浅入深揭秘JavaScript类型转换(最全总结篇)(二)

简介: 深度剖析之由浅入深揭秘JavaScript类型转换(最全总结篇)(二)

隐式强制类型转换

  • + 运算符既能用于加法运算,也能用于字符串拼接。
var a = "42";
var b = "0";
var c = 42;
var d = 0;
a + b; // "420"
c + d; // 42
  • • S: 如果 + 运算符中其中一个操作数是字符串,则执行字符串拼接,否则执行加法运算。

隐式强制类型转换为布尔值

  • • (1) if (..) 语句中的条件判断表达式。
  • • (2) for ( .. ; .. ; .. ) 语句中的条件判断表达式(第二个)。
  • • (3) while (..) 和 do..while(..) 循环中的条件判断表达式。
  • • (4) ? : 中的条件判断表达式。
  • • (5) 逻辑运算符 ||(逻辑或)和 &&(逻辑与)左边的操作数(作为条件判断表达式)。
  • || 和 &&
  • • 他们的返回值两个操作数中的其中一个
var a = 42;
var b = "abc";
var c = null;
a || b;     // 42
a && b;     // "abc"
c || b;     // "abc"
c && b;     // null
  • || 和 && 操作符会对第一个操作数进行条件判断,且会对第一个操作数进行隐式类型转换(会通过 toBoolean 操作),然后再进行条件判断。
  • || 运算符,如果条件判断结果为true, 就返回第一个操作数的结果。如果为 false, 就返回第二个操作数的结果。
  • && 运算符则相反,如果条件判断结果为 true 就返回第二个操作数结果,如果为 false, 就返回第一个操作数的结果。
a || b;
// 大致相当于
a ? a : b;
a && b;
// 大致相当于
a ? b : a;

宽松相等(==)和严格相等(===)

  • • 宽松相等 == 与严格相等 === 都是用于判断两个值是否相等。但他们之间有一个重要的区别,特别是在判断条件上
  • • 在之前的了解和很多文章中很多人这样聊到: == 检查值是否相等, === 检查值和类型是否相等。这么说听起来蛮有道理,但不够准确。正确的解释应该是: == 允许在相等比较中进行强制类型转换,而 === 不允许

两种操作符的性能

  • • 根据第一种(== 检查值是否相等, === 检查值和类型是否相等)解释:严格相等(===) 比 宽松相等(==) 似乎做的事情更多,因为它还要检查值的类型。而第二种(== 允许在相等比较中进行强制类型转换,而 === 不允许) 解释: 宽松相等(==) 似乎做的事情更多,如果值类型不同还需要进行强制类型转换。
  • • 这样下来,有人觉得 == 比 === 慢,实际上确实 == 在强制类型转换的时候需要花费时间,但这个时间为微妙级的(百万分之一秒)。所以,在进行比较两个值类型相同的情况下,使用 == 与 === 没有什么区别如果两个值类型不同,这时候就要考虑有没有强制类型转换的必要,有就用 ==,没有就用 ===,不需要在乎性能
  • • == 和 === 他们都会检查操作数的类型,区别在于操作数类型不同时他们的处理方式的不同。

字符串和数字之间的相等比较

var a = 42;
var a = "42";
a === b; // false
a == b; // true
  • • a === b 因为没有强制类型转换,所以 a === b 为 false, 也就是 42 和 "42" 不相等。
  • • a == b 因为是宽松相等,即当两个值类型不同时,则对其中一个值进行强制类型转换。那如何转换,是转换 a,还是转换 b 呢?
  • • ES5 规范 11.9.3.4-5 规则:
  • 如果 Type(x) 为数字,Type(y) 为字符串,则返回 x == toNumber(y) 的结果
  • 如果 Type(x) 为字符串,Type(y) 是数字,则返回 toNumber(x) == y 的结果
  • • 所以根据以上规则,"42" 会被进行 toNumber 转换然后进行相等比较,所以 42 == 42 为 true。

其他类型与布尔类型之间的相等比较


  • • == 很容易出错的一个地方就是 true、false 和其他类型之间的相等比较。
var a = "42";
var b = true;
a == b; // false
  • • 我们知道变量 a 为字符串 "42" 是一个真值,那为什么 a == b 会返回 false 呢?
  • • ES5 规范 11.9.3.6-7 规则:
  • 如果 Type(x) 是布尔类型,则返回 toNumber(x) == y 的结果
  • 如果 Type(y) 是布尔类型,则返回 x == toNumber(y) 的结果
  • • 所以根据以上规则, Type(b) 为布尔类型,所以会对 b 进行 toNumber 操作,然后就是 true = 1, 根据字符串与数字之间的比较规则可得出 42 != 1,所以结果为 false。
  • • 所以现在你搞懂了吗???
  • • "42" 是一个真值没错,但 "42" == true 并没有发生布尔值比较和强制类型转换。这里并不是 "42" 转换为布尔值,而是 true 进行 toNumber 操作。
  • • 所以我们要搞清 == 对不同类型的组合会怎样处理,== 两边的布尔值会进行 toNumber 操作
  • • 所以建议大家不管什么情况下都不要使用 == true 和 == false 来判断。但对于 === 来说,它不会发生强制类型转换,所以不需要进行 toNumber 操作。
var a = "42";
// 不要这样用,条件判断不成立:
if (a == true) {
    // ..
}
// 也不要这样用,条件判断不成立:
if (a === true) {
    // ..
}
// 这样的显式用法没问题:
if (a) {
    // ..
}
// 这样的显式用法更好:
if (!!a) {
    // ..
}
// 这样的显式用法也很好:
if (Boolean( a )) {
    // ..
}

null 和 undefined 之间的相等比较

  • • ES5 规范 11.9.3.2-3 规则:
  • 如果 x 为 null, y 为 undefined, 则结果为 true
  • 如果 x 为 undefined, y 为 null, 则结果为 true
  • • 在 == 中 null 和 undefined 相等且他们也与自身相等,除此之外不存在这种情况。也就是说在 == 中的 null 和 undefined 是一回事,可进行隐式的强制类型转换
var a = null;
var b;
a == b;     // true
a == null;  // true
b == null;  // true
null == undefined;  // true
null == null;  // true
undefined == undefined;  // true
a == false; // false
b == false; // false
a == "";    // false
b == "";    // false
a == 0;     // false
b == 0;     // false
  • • 所以我们可将 null 和 undefined 作为等价来处理
var a = doSomething();
if (a == null) {
    // ..
}
  • • 以上的 if 判断语句只有当 a 为 null 或 undefined 时才成立,除此之外都不成立,包含 0, false 和 ''。

对象与非对象之间的相等比较

  • • 关于对象(对象、函数、数组)与基本类型(字符串、数字,布尔值)之间的相等比较。
  • • ES5规范 11.9.3.8-9 规则如下:
  • 如果 Type(x) 是字符串或数字,Type(y) 是对象,则返回 x == toPromitive(y) 的结果
  • 如果 Type(x) 是对象,Type(y) 是字符串或数字,则返回 toPromitive(x) == y 的结果
var a = 42;
var b = [ 42 ];
a == b; // true
  • • [ 42 ] 首先调用 toPromitive 抽象操作,返回 "42",变成 "42" == 42,然后又变成 42 == 42,最后二者相等。
相关文章
|
7月前
|
JavaScript 前端开发
JavaScript基础语法(类型转换)
JavaScript基础语法(类型转换)
53 0
|
2月前
|
JavaScript 前端开发 安全
如何处理 JavaScript 中的类型转换错误?
【10月更文挑战第9天】处理类型转换错误需要综合运用多种方法和策略,同时要保持对潜在问题的警惕性。通过合理的错误处理,可以提高程序的健壮性,减少因类型转换错误带来的负面影响。
35 0
|
2月前
|
JavaScript 前端开发
JS隐式类型转换规则
【10月更文挑战第9天】 不同的 JavaScript 引擎可能在隐式类型转换的具体实现上存在一些细微差别。理解这些隐式类型转换规则对于正确处理数据和避免错误非常重要。
20 0
|
3月前
|
JavaScript 前端开发
JavaScript 类型转换
JavaScript 类型转换
27 4
|
5月前
|
开发框架 JavaScript 前端开发
JavaScript框架比较与选择:技术深度剖析
【7月更文挑战第23天】选择正确的JavaScript框架是项目成功的关键。React.js、Vue.js、Angular和Svelte等前端框架各有千秋,分别适用于不同的项目需求。同时,Node.js及其后端框架为服务器端开发提供了强大的支持。开发人员应根据项目的复杂性、性能要求、开发周期以及团队技能等因素综合考虑,选择最适合的框架。随着技术的不断发展,未来还将涌现更多优秀的JavaScript框架,为开发者带来更多选择和可能性。
|
4月前
|
JavaScript 前端开发
JS:类型转换(四)从底层逻辑让你搞懂经典面试问题 [ ] == ![ ] ?
JS:类型转换(四)从底层逻辑让你搞懂经典面试问题 [ ] == ![ ] ?
|
5月前
|
JavaScript
js【详解】自动类型转换
js【详解】自动类型转换
28 0
|
5月前
|
JavaScript 前端开发
|
7月前
|
JavaScript 前端开发 Python
javascript中的强制类型转换和自动类型转换
javascript中的强制类型转换和自动类型转换
|
7月前
|
存储 JavaScript 前端开发
深度剖析JavaScript中的变量世界:概念、用例与避坑指南
【4月更文挑战第3天】探索JavaScript变量:了解var、let、const的差异,掌握数据类型、用例及避免错误的策略。声明变量时注意作用域和可变性,如var的函数作用域,let和const的块级作用域。理解基本数据类型(Number、String等)和对象类型。示例包括用户输入、计算、控制流程和函数参数。警惕未声明、作用域混淆、类型不匹配和未初始化的错误,遵循最佳实践,如明确命名、避免冗余和适时复用,利用类型检查工具提升代码质量。
167 1