1.js数据类型

90 阅读3分钟

种类

  • 基本数据类型(值类型、原始类型)
    • number
      • NaN
      • Infinity
    • string
    • boolean
    • null
    • undefined
    • symbol
      • static Symbol
      • Symbol.prototype
    • bigint
  • 引用数据类型
    • object
      • 普通对象
      • 数据对象
      • 正则对象
      • 日期对象
      • JSON对象
      • Set
      • Map
      • ... 引申面向对象时,prototype原型对象、原型链
    • function
      • 普通函数
      • 构造函数
      • 箭头函数
      • 生成器函数
      • ...

类型转换

 /**
 * number 数字
 *  + 正数 负数 零 小数 。。。
 *  + NaN: not anumber 不是一个有效数字,但属于number类型
 *    + NaN和NaN本身不相等,和其他值也都不等
 *    + isNaN([value]): 检测当前值是否为有效数字,true为非有效数字
 *    + Object.is(NaN, NaN) // -> true 「is方法做了特殊处理」
 *  + Infinity: 无限大 Infinity:无限小
 *
 * 把其他数据类型转换为number类型
 *  + 显式转换 「Number([value]) | parseInt/parseFloat([value]) 」两者底层处理规则是不一样的
 *  + 隐式转换 基于Numner([value])机制
 *    + 数学运算
 *    + 基于==比较的时候
 *    + isNaN([value])
 *    + ...
 */
// console.log(typeof NaN) // -> number
// console.log(typeof Infinity) // -> 'number'

// console.log(NaN == NaN) // -> false
// console.log(NaN === NaN) // -> false
// console.log(Object.is(NaN, NaN)) // -> true


/**
 * string字符串
 *  + '' / ""
 *  + `` 模板字符串
 *
 * 把其他值转换为字符串
 *  + 显示转换: String([value]) 或者 [value].toString「->延展出数据类型检测」
 *  + 隐式转换:
 *      + 加号除了数学运算,还会产生字符串拼接
 */
// let n = '10'
// let m = 10
// console.log(10 + n) // 1010 ’+‘有一边出现了字符串「前提有两边」会变为字符串拼接
// console.log(+n) // 10 '+'只有一边,把值准换为数字
// console.log(++n) // 11 '++'和上面一样,也是把值转换为数字,但是还会自身在累加1
// // i = i+1 i+=1 这两个一样
// // i++ / ++i 大部分情况是一样的,但如果i本身的值是字符串则不一致「上面会处理为字符串拼接,下面是数字累加」


// // 如果”+“两边,有一边是对象,则也可能会成为字符串拼接
// //  + 10+{} 或者 10+{name:'zhufeng'}  -> '10[object object]'
// //  + 10 + [10] -> '1010'
// //  特殊:
// //  + 10+new Number(10) -> 20
// //  + {}+10 或者 {name:'zhufeng'}+10 -> 10 「原因:{...}没有参与运算,浏览器认为其是一个代码块,计算’+10‘」
// //    + ({}+10) -> '[object object]10'
// //    + let x={}+10 -> '[object object]10' 下面两种不论包起来还是赋值,从语法分析上都要参与到计算中
// //  + ...
// // 底层机制:对象再做数学运算的时候 (10+new Number(10) -> 20)
// //  + 检测对象的 Symbol.toPrimitive 这个属性值,如果有则基于这个值进行运算,如果没有
// //  + 检测对象的 valueOf 这个值「原始值:基本类型值」,如果有则基于这个值进行运算,如果不是原始值
// //  + 获取对象的 toString() 把其变为字符串 -> 如果是'+'处理,则看到字符串了,所以变为字符串拼接
// //  + 如果最后就是想变为数字,则再把字符串转换为数字即可
// // let obj = {}
// // console.log(10 + obj)
// let obj = {
//   [Symbol.toPrimitive]: function (hint) {
//     // hint: 记录浏览器识别出来的,你会把其转换为什么类型的 default/string/number...
//     // console.log(hint) // -> default 引申Numner(obj),String(obj)
//     return 10
//   }
// }
// console.log(10 + obj) // -> 20


// // console.log({} + m)
// // let res = {} + m
// // console.log(res)

// // console.log(m + {})
// // console.log(m + new Number(10))
// // console.log(m + {
// //   value: 10
// // })




/**
 * Symbol(): 创建唯一值
 *  + 给对象设置一个Symbol属性:唯一属性 「减少属性处理上的冲突」
 *  + 宏观管理一些唯一的标识的时候,也是用唯一值
 */
// new Symbol() // Uncaught TypeError: Symbol is not a constructor
// let xx = Symbol()
// console.log(Symbol() === Symbol()) // -> false
// console.log(Symbol('AA') === Symbol(AA)) // -> false


// let obj = {
//   [Symbol()]: 100
// }
// console.log(obj[Symbol()]) // -> undefined

let x = Symbol()
let obj = {
  [x]: 100
}
console.log(obj[x]) // -> 100

/**
 * 很多js的内置原理都是基于这些Symbol的属性来处理的
 * Symbol.toPrimitive
 * Symbol.hasInstance
 * Symbol.toStringTag
 * Symbol.iterator
 */


/**
 * BigInt:大数
 *   + BigInt([num])
 *   + xxxn
 * 大型项目中,服务器返回客户端的数据中可能出现大数「服务器数据库中可以基于longint存储数值,这个值可能会超过最大安全数字」
 */
 // Number.MAX_SAFE_INTEGER 9007199254740991 最大安全数
 // Number.MIN_SAFE_INTEGER 最大安全数
 // 超过最大安全数进行计算,值是不准确的