js数据类型深层挖掘

263 阅读5分钟

数据类型

基本数据类型:(原始数据类型)
 string 
 number     NaN/Infinity
 boolean    true/false
 null
 undefined

 symbol 创建唯一值
 bigint

 引用数据类型
  object 
      function

一些特殊的例子

console.log(typeof NaN)  // 'number'
console.log(NaN == NaN)  // false
let a = NaN
console.log(a == a)      // false

let x = 10
if(isNaN(x)) {     // 进不来
    console.log('是真的有效数字')
}

console.log(Object.is(NaN, NaN))   // true 可以理解成 === 只是对 NaN做了特殊的处理

let s = Symbol('aa')
console.log(s == s)  // true  与 NaN 不一样
console.log(Symbol('aa') == Symbol('aa'))  // false  可以理解为比地址

做题

let res = parseFloat('left:200px')
if(res === 200) {
    alert(200)
}else if(res === NaN) {   // NaN === NaN   false
    alert(NaN)
}else if(typeof res === 'number') {
    // typeof NaN === 'number'
    alert('number')
}else {
    alert('Invalid Number')
}
number

学历不好抱怨有毛用,提高技术就行了,人家考研,靠985也不容易哈。拿起键盘干就完了。

为啥分两大类数据类型?

ECStack?

GO ?

VO 谁什么?

vo(varibale object) 变量对象,

基本类型存储

  1. 基本类型都是存储在栈内存空间里面的
  2. var a = 100 相当于先在栈里面存一个100,再声明一个变量a指向他。
var a = 10
var b = a
b = 999
console.log(a)  // 10 值拷贝赋值

引用类型存储

  1. 引用类型不会直接存在栈中,他会开辟一个堆内存(也是计算机分配的一个空间),用来存储自己的真实内容,每个堆都有一个16进制的地址。
  2. 把16进制的地址放到栈内存中,供变量来调用。
  3. 基本类型都是按值操作的,引用类型都是按地址操作的。
var obj = {
    val: 10
}
var obj1 = obj   // 指向同一个栈内存中的值,这个变量又指向一个堆内存中的真实值
obj1.val = 999
console.log(obj.val)  // 999

指向一个新的引用对象

  1. 当重新指向之后,o1 就和之前对象没关系了。
var o = {
    val: 10
}
var o1 = o   // o o1 执行同一个堆内存空间
o1 = {       // 把 o1 重新指向
    val: 999
}
console.log(o.val)   // 10 

做题

var a = b = 10 赋值

连等赋值以右侧先运算

var a = b = 10

// 相当于
b = 10
a = 10

以下这种情况说明成员访问的优先级是比等号赋值高很多的,所以先计算他。

a.x = b = 10

// 相当于 
a.x = 10
b = 10
var a = {n: 1}
var b = a
a.x = a = {n: 2}
console.log(a.x)  // undefined
console.log(b)    // {n:1,x:{n:2}}

js 对象的key

  1. js对象的key不能是引用类型。
  2. js对象的key可以是任意的普通类型,也可以是symbol类型
  3. 如果key是除了string之外的类型,访问的时候也可以通过string进行访问。
var a = {}
    b = '0'
    c = 0;
a[b] = 999
a[c] = 1
console.log(a[b])
1

symbol 当做对象的key

var a = {}
var b = Symbol('1')
var c = Symbol('1')
a[b] = 99
a[c] = 100

console.log(a[b])  // 99
99

对象不能当做Key

都会被转换成字符串。[object Object]

var a = {}
var b = {
    val: 100
}
var c = {
    val: 99
}
a[b] = 1
a[c] = 10
console.log(a[b])   // 10

数组当做参数

赋值=右边是一个新的引用类型的话,就是开辟一个新的堆内存空间。如果指向原来的对象的引用那么两个变量将指向同一个堆地址

var x = [12, 23]
function fn(y) {
    y[0] = 100
    y = [100]
    y[1] = 200
    console.log(y) // [100, 200]
}
fn(x)   
console.log(x)    // [100, 23]

作用域链

当前私有上下文代码执行时,遇到一个变量,首先在当前作用域寻找,如果找到了,就操作当前环境下的变量,如果没找到,就一直往上找,一直找到全局上下文。

数据类型转换规则

把其他类型转换为Boolean类型

  1. !转换为 boolean 后取反。
  2. !! 转换为 boolean 类型
  3. Boolean(val)
  4. 五种情况的值会变成false''0undefinednullNaN、其余的都是 true。

== 两等号转换规则

  1. 两边类型一样的几个特点
{} == {} false   // 对象比较的是地址
[] == []  flase
NaN == NaN  false
  1. 两边类型不一样的转换规则
    1. null == undefined // true
    2. null === undefined // false
    3. 剩下的null/undefined和其他的任意类型数值都不相等
    4. 字符串 == 对象 要把字符串转换成对象
    5. 如果 == 两边数据类型不一致都是需要转换成数字再进行比较
对象 == 布尔 (都转为数字)
对象转为数字:先局域valueOf()获得原始值,没有原始值再去 toString(),再转为数字
[] => '' => 0
console.log([] == false)

把数组转换成布尔类型后取反
console.log(![] == false)

其他类型转换为 number

console.log(Number(''))     // 0
console.log(Number('10'))   // 10
console.log(Number('10px')) // NaN
console.log(Number(true))   // 1
console.log(Number(false))  // 0
console.log(Number(null))   // 0
console.log(Number(undefined))  // NaN
console.log(Number(Symbol(10))) // 报错
console.log(Number(BigInt(10))) // 10

对象转为数字,应该先valueOf() ,没有原始值再toString变为字符串,最后把字符串转为数字

parseInt

parseInt机制:从字符串左侧第一个字符开始(忽略空白字符),查找有效数字字符串(遇到非有效数字字符停止查找,不论后面是否还有数字字符,都不再找了) 把找到的有效数字字符串转为数字,如果一个都没有找到结果就是 NaN(parseFloat比他多识别一个小数点)

3\4\5\6要重新看