1. 值类型转换

值从一种类型转换为另一种类型,通常称为类型转换,强制类型转换都是发生在动态类型语言的运行时(runtime)

  • 隐式强制类型转换
  • 显式强制类型转换
    1. var a = 42;
    2. var b = a + ""; // 隐式
    3. var c = String(a); // 显式

    2. 抽象值操作

    JSON字符串化
    对于大多数简单值来说,JSON字符串化和toString()效果基本相同
    1. JSON.stringify(42); // "42"
    2. JSON.stringify("42"); // ""42"" (含有双引号)
    3. JSON.stringify(null); // "null"
    安全的JSON值是能够呈现为有效JSON格式的值,不安全的JSON值:undefined,function,symbol和包含循环引用(对象之间相互应用,形成一个无限循环)对象,是无法处理的

JSON.stringify(..)在对象中遇到undefined,function和symbol会自动忽略,但是在数组会返回null来占位

  1. JSON.stringify(undefined); // undefined
  2. JSON.stringify(function(){}); // undefined
  3. JSON.stringify([1,undefined,function(){},4]);// "[1,null,null,4]"
  4. JSON.stringify({a:2,b:function}); // "{a:2}"
  5. // 对包含循环引用的对象执行JSON.stringify(..)会报错

2.1 介绍JSON.stringify(..)几个计较好用的功能

  • 可选参数replacer

    我们可以向JSON.stringify(..)传递一个可选参数replacer,是数组或者是函数,用来控制对象序列化过程中数据的处理

  1. var a={
  2. b:42,c:"42",d:[1,2,3]}
  3. JSON.stringify(a,["b","c"]); // "{"b":42,"c":"42"}"
  4. JSON.stringify(a,function(k,v){
  5. if(k!=="c"){return v}
  6. });// "{"c":"42","d":[1,2,3]}}"
  • 可选参数space

    用来指定输出的缩进格式

  1. var a = {
  2. b:42,
  3. c:"42",
  4. d:[1,2,3]
  5. }
  6. JSON.stringify(a,null,3);
  7. // {
  8. // "b":42,
  9. // "c":"42",
  10. // "d":[
  11. // 1,
  12. // 2,
  13. // 3]
  14. // }

2.2 ToNumber

true转换为1,false转换为0,undefined转换为NaN,null转换为0

2.3 ToBoolean

转换为false

  • undefined
  • null
  • false
  • +0,-0,NaN
  • “”

假值之外的都是真值,会使用Boolean(..)转换为true

2.4 奇特~运算符

~运算符,就是字位操作”非“,首先将值强制类型转换为32位数字,然后执行字位操作”非“(对每一位字位进行反转)

~x大致等同于 -(x+1)

  1. ~42; // -(42+1) ==> -43

有什么用?可以~和indexOf()一起可以将结果强制类型转换为真/假值

  1. var a = "Hello World"
  2. ~a.indexOf("ol");// -4 =>真值
  3. // ~(-1) => -(-1+1) => 0
  4. if(~a.indexOf("ol")){
  5. // 找到匹配的
  6. }
  7. if(!~a.indexOf("ol")){
  8. // 不匹配的
  9. }

3. || 和 &&

”逻辑运算符“,准备来说是”选择器运算符“,因为它的返回值是两个操作数中的一个(且仅一个)

  1. var a=42;
  2. var b="abc";
  3. var c=null;
  4. a||b; // 42
  5. a&&b; // "abc"
  6. c||b; // "abc"
  7. c&&B; // null

||和&&首先会对第一个操作数执行判断,如果不是布尔类型,会进行toBoolean强制类型转换,在执行判断

  • ||,如果条件判断结果为true,就返回第一个操作数的值,如果为false就返回第二个操作数的值
  • &&,如果条件判断结果为true,就返回第二个操作数的值,如果为false就返回第一个操作数的值
    1. // 短路机制
    2. function foo(){
    3. a=a ||"hello";
    4. b=b ||"world";
    5. console.log(`${a}${b}`)
    6. }
    7. foo(); // "hello world"
    8. foo("yeah", "yeah!");// "yeah yeah!"
    9. // 或者对于上面👆的或运算,也是可以转而使用?:三元表达式

”把关“,就是用&&实现

  1. function foo() {
  2. console.log(a);
  3. }
  4. var a =42;
  5. a && foo(); // 42

如果||和&&使用在if和for语法里面,其实最后是存在一个隐式强制转换

4. 宽松相等和严格相等

==和===,解释一下,==允许在相等比较中进行强制类型转换,而===不允许

性能的话,他们都是使用相同的算法去执行,==会多一个类型的转换,但是丝毫没有影响,只是微秒级(百万分之一)的差别,所以不用在乎性能的比对

其他类型和布尔值类型之间的比较

特别提醒⚠️:其他类型和布尔值类型之间的比较,是有点理解上的出入

  1. var a = "42";
  2. var b = true;
  3. a==b; // false
  4. // 这里不是”42“转换为布尔值(true),而是true转换为1,”42“转换为42

˙重点是我们要搞清楚==对不同的类型组合怎样处理,==两边的布尔值被强制类型转换为数字🔢,个人建议无论什么情况下,不要使用==true和==false

最好的情况,是使用===来避免不经意的强制类型转换的坑,同时也是省事,也是为了安全起见