# 1、数据类型

  • 基本数据类型:7种 (number string boolean null undefined symbol bigint)
  • 引用数据类型:2种
    • object ( 普通对象 数组对象 日期对象 正则对象 Math数学函数对象 prototype原型对象)
    • function
  • Sybbol([value]): 创建唯一值
  console. log(Symbol('A') == Symbol('A')) => false
  • 数字类型中比较奇怪的值

NaN指某个值不是一个有效数字,但属于Number类型
NaN!= NaN 它和谁都不相等,包括和自己本身也不相等
isNaN检测这个值是否为有效数字,如果不是有效数字,返回true,是有效数字返回false

  1NaN 不是有效数字,但属于number类型
  consol. log(typeof NaN); // "number"
  consol. log(NaN === NaN); // false
  Object. is(NaN, NaN); // => true 检测两个值是否相等

  2**isNaN**检测这个值是否为****有效数字
  console. log(isNaN(10)); // false
  console. log(isNaN('AA')); // true => 
  // 在检测的时候,如果当前这个值不是数字类型,
  // 先隐式转换成数字类型(Number),然后再检测是否为 非有效数字 

  3Infinity无穷大的值
  console. log(Infinity); // Infinity

例题:

  let res = parseFloat('left:200px'); // => NaN
  if(res===200){

    alert(200);

  }else if(res===NaN){  // NaN!= NaN

    alert(NaN); 

  }else if(typeof res==='number'){  // => typeof NaN = 'number'

    alert('number');

  }else{

    alert('Invalid Number');

  }

  typeof null ==> 'object' 不属于对象,而是因为二级制存储值以000开头了

# 2、把其它数据类型转换为数字的方法

  • 强转换(基于底层机制转换的) Number([value])

    • isNaN('12px') 先把其它类型值转换为数字再检测
    • Number() 中的字符串必须保证都是有效数字才会转换为数字,否则都是NaN
    • 对象变为数字,应该先valueOf,没有原始值再toString变为字符串,最后把字符串转换为数字
    把其它类型转换为数字 Number机制:
    Number(''); // 0
    Number('10'); // 10
    Number('10px'); // NaN 只要出现非有效数字,结果都是NaN
    Number(true); // 1
    Number(false); // 0
    Number(null); // 0
    Number(undefined); // NaN
    Number(Symbol(10)); // 报错
    Number(BigInt(10)); // 10
    
  • 弱转换(基于一些额外的方法转换) parseInt([value])/parseFloat([value])

注意

undefined转变为数字为 NaN
null转变为数字为 0

# parseInt 机制 beta parseInt

  • 处理的值是字符串时,从字符串左侧第一个字符开始查找有效数字字符(遇到非有效数字字符,则停止查找),把找到的有效数字字符一次转换为数字

如果一个都没找到结果就是NaN(parseFloat比他多识别一个小数点)

  • 如果处理的值不是字符串,需要先转为字符串

# Number

直接调用浏览器最底层的数据类型检测机制来完成
Number() 中的字符串必须保证都是有效数字才会转换为数字,否则都是NaN

# "+"号

  • "+"在JS中左右两边出现字符串,则变为字符串拼接(有特殊性)
  • “+”遇到对象也会变为字符串拼接(因为原本把对象转换为数字,但是对象转数字需要先转换为字符串,则"+"遇到字符串直接变为字符串拼接 1+[])

例题1

  parseInt("") // NaN
  Number("") // Number(null) => Number(0) => 0
  isNaN("") // 先把“”转换为数字(隐式 Number) isNaN(0) false
  parseInt(null) // 弱转换 先把null转换为字符串 => parseInt("null") => NaN
  Number(null) // Number(0) => 
  isNaN(null) // 隐式转换Number() isNaN(0) false
  parseInt("12px") // 弱转换 12
  Number("12px") // 不是有效数字 故NaN
  isNaN("12px") // isNaN(NaN) true
  parseFloat("1. 6px")+parseInt("1. 2px")+typeof parseInt(null); 
  // 1. 6 + 1 + typeof parseInt("null") => 2. 6 + 'number' => '2. 6number'
  isNaN(Number(!! Number(parseInt("0. 8")))); 
  // isNaN(Number(!! Number(0))) => isNaN(Number(false)) => isNaN(0) => false
  typeof !parseInt(null) + !isNaN(null); 
  // typeof ! NaN + !false => 'boolean' + true => 'booleantrue'

例题2

  let result = 10 + false + undefined + [] + 'Tencent' + null + true + {}

  解题步骤:
  10 + false => 10 (+ 左右没遇到对象或字符串,故进行数学运算)
  10 + undefined => NaN
  NaN + [] => "NaN"
  "NaN" + "Tencent" => "NaNTencent"
  ... 都是字符串拼接
  "NaNTencentnulltrue" + {}. toString() => "NaNTencentnulltrue[object Object]"

  consol. log(result) => "NaNTencentnulltrue[object Object]"

例题3 特殊性
"+"即使一边出现字符串或者对象,也不一定是字符串拼接:++i/+i/i++ 这种情况是数学运算

  let n = "10"
  console. log(++n); // 11
  console. log(+n); // 10

  {}+0
  // 左边的{}认为是一个代码块,不参与运算
  // 运算只处理的是+0 => 0
  // function fn(){}+0

  ({}+0) 则看作一个整体参与数学运算
  "[object Object]0"

  0+{} 这种情况是数学运算
  "0[object Object]"

  +{}
  +{}. toString() => + [object Object] => NaN

# 3、数据类型转换的4大核心标准

# 3-1 把其他数据类型转换为Number类型

  1. 特定需要转换为Number的
  • Number([val])
  • parseInt/parseFloat([val])
  1. 隐式转换(浏览器内部默认要先转换为Number在进行计算的)
  • isNaN([val])
  • 数学运算(特殊情况:+在出现字符串的情况下不是数学运算,是字符串拼接)
  • 在==比较的时候,有些值需要转换为数字再进行比较
  • ...

# 3-2 把其它数据类型转换为字符串

  1. 能使用的办法
  • toString()
  • String()
  1. 隐式转换(一般都是调用其toString)
  • 加号运算的时候,如果某一边出现字符串,则是字符串拼接
  • 把对象转换为数字,需要先toString()转换为字符串,再去转换为数字
  • 基于alert/confirm/prompt/document. write... 这些方式输出内容,都是把内容先转换为字符串,然后再输出的
例题:
String(null) => "null"
String(undefined) => "undefined"

({}). toString() => "[object, Object]" // Object. prototype. toString()
把其它类型转换为字符串,一般都是直接“”包起来
只有{}普通对象调取toString是调取Object. prototype. toString,不是转换为字符串 
而是检测数据类型,返回结果是 "[object, Object]"

# 3-3 把其它数据类型转换为布尔

  1. 基于以下方式可以把其它数据类型转换为布尔
  • ! 转换为布尔值后取反
  • !! 转换为布尔类型
  • Boolean([val])
  1. 隐式转换
  • 在循环或者条件判断中,条件处理的结果就是布尔类型值
  • 规则:只有 ‘0、NaN、null、undefined、空字符串’ 五个值会变为布尔的false,其余都是true
例题:
console. log(![] == false); // true

! 取反运算符的优先级高于 == <br>
1![] 把数组转换为布尔类型,然后取反 [] => true![] => false <br>
2false == false 类型相同 <br>
3=> true

# 3-4 在==比较的过程中,数据转换的规则

【类型一样的几个特殊点】

  • {}=={}:false 对象比较的是堆内存的地址
  • []==[]:false
  • NaN==NaN:false
  • 【类型不一样的转换规则】
    1. null==undefined:true,但是换成===结果是false(因为类型不一致),剩下null/undefined和其它任何数据类型值都不相等
    1. 字符串==对象 要把对象转换为字符串
    1. 剩下如果==两边数据类型不一致,都是需要转换为数字再进行比较
例题:     
console. log([] == false); // true

除字符串和对象相比,都转为数字比较。<br>
对象 == 布尔 都转换数字(隐式转换)

1、对象转换为数字:先toString转换为字符串(应该是先基于valueOf获得原始值,没有原始值再去toString),再转为数字 []. toString() => '''' => 0
2false => 0
3=> true