Js数据类型和 栈、堆动态讲解

9大数据类型

数据类型分类

  • 基础类型 7
    • number
    • string
    • boolean
    • null
    • undefined
    • bigint
    • symbol
  • 引用类型 2
    • object
      • 普通对象 Map
      • 实例对象
      • 数组对象 Set
      • 正则对象
      • 日期对象
      • prototype原型对象
    • function
  • isNaN NaN Infinity

基础数据类型

string 字符串

使用 '' ""和反引号``包起来的都是字符串
其他类型转换为字符串类型

  • [val].toString()
    • 其他类型转换为字符串,一般是使用‘’包起来
    • {}普通对象调取toSring是调取的Object.prototype.toString,不是转换为字符串而是检测数据类型,返回结果是"[object Object]"
  • String()
  • 隐式转换(一般调用toString)
    • + 加法运算,某一侧出现字符串,存在字符串拼接
    • 把对象转换为数组,需要先toString()转化为字符串,在转化为数字
    • 基于alert/confirm/document.write…这些方式输出的内容,都是把内容先转化为字符串,然后再输出
  • 测试题
let a = 10 + null + true + [] + undefined + '珠峰' + null + [] + 10 + false


//10+null=10
//10+true=11
//11+[]=>11+''=>'11'
//'11'+undefined=>11undefined
//'11undefined'以后为字符串拼接=>"11undefined珠峰null10false"

JS 中的加减乘除进行数学运算(如果遇到的不是数字类型,需要基于Number()方法转换位数字,在运算)加法遇到字符串会进行字符串拼接

  • 字符串拼接时注意:
    • 先找字符串[] {} '',从头到字符前一个,数字转换相加,以后拼接字符串
    • [] -> ‘’
    • {} -> ‘[object Object]’’
    • 数字 + undefined = NaN

number 数字

其他类型转换为数字类型

  • Number([val]):先执行toString(),在进行数字转换
Number('1') //1
Number('') //0
Number({})  //NaN
Number({a:1}) //NaN
Number(undefined) //NaN
Number(null) //0
Number([])  // 0 [].toString()=>''->0
Number(['1']) // 1->['1'].toString()->'1'->1
Number([1,3]) //NaN
Number(Symbol(10)) //报错
  • parseInt/parseFloat([val],[进制]):如果val是字符串,则从左至右依次查找有效数字字符,直到遇到非有效数字,停止查找(即使后面还有数字,也不返回),找到的字符当做数字返回,无有效数字返回 NaN
    • parseInt([val],[radix]),radix是进制不写和0都是10进制,如果value以0x开头默认为16进制
    • 进制取值范围:2~36之前,不在函数返回结果为NaN
    • 把[value]看做[radix]进制,最后把[redix]转换为十进制
parseInt('') //NaN
parseInt({}) //NaN
parseInt([]) //NaN 
parseInt(null) //NaN
parseInt(undefined) //NaN 
parseInt('14px') //14
parseInt('14px3') //14

  • 隐式转换
    • isNaN([val])
    • 数学运算(+运算比较特殊,可能是字符串拼接)
    • == 进行比较时,可能出现把其他类型转换为数字的情况
  • ++ii++都是数学中的累加1
let i = 1
5 + (i++) // 5 + 1 = 6、 i = 2

i = 1
5 + (++i) //5 + 2 = 7、 i = 2 
  • 特殊值NaN
    • NaN == NaN false
    • Object.is(NaN,NaN) true
    • isNaN(NaN) true
  • Infinity 无穷大

把一个值转化为十进制 :[位权值:每一位的权重,…个位是0,十位是1…]

  • 例:147(八进制)-> 十进制 =

    • 1*8^2 + 4*8^1 + 7*8^0
    • 1*8*8 + 4*8 +7*1
  • 例:12.88(4进制)-> 十进制 =

    • 1*4^1 + 2*4^0 + 8*4^-1 + 8*4^-2
    • 1*4 + 2*1 + 8*(1/4) + 8*(1/(4*4))

boolean 布尔型

只有两个值:true false
其他类型转换为布尔类型

  • 0 null NaN undefined ''五个值转换为false,其余转换为true
  • Boolean([val])
  • !! 相当于转换为布尔
  • ! 转化为布尔取反
  • 隐式转换
    • 除了在if== !== === >=都要先把值转换为布尔类型
function getNum(){
    if('3px'+3){ //字符串拼接
        return 3
    }
}
getNum() //3

function getNumber(){
    if('3px'-3){  //NaN-3->NAN
       return 3
    }else{
    return 2
    }
}
getNumber() //2

在==比较的过程中,数据转换规则

  • 类型一样的几个特殊点
    • {} == {} false 对象比较的是最内存的地址
    • [] == [] false
    • NaN == NaN false
  • 类型不一样的转换规则
    • null==undefied:true,但是换成 === 则为false,(因为类型不一致),剩下的null/undefined和其他任何数据类型值都不相等
    • 字符串==对象 要把对象转换为字符串
    • 剩下如果==两边数据类型不一致,都是需要转换为数字在比较
  • 练习题
console.log([] == false)

console.log(![] == false)

  • 练习题解析
    • [] == false
      • 对象==布尔 都转换为数字
      • 对象转换为数字:先toString转换为字符串(应该是先基于valueof获得原始值,没有原始值再去toString)在转换为数字 [] -> '' -> 0
      • false -> 0 true -> 1
      • 0 == 0 -> true
    • ![] == false
      • !的计算优先级大于==,先计算![] 数组转换为布尔然后去反false
      • false == false -> true

null 空对象指针

意料之中,设置默认值,后期赋值

一般使用null作为初始值,0在栈内存中有自己的存储空间,占位

undefined 未定义

意料之外

let a;//undefined

symbol 创建唯一值

Symbol([value])

console.log(Symbol('A')==Symbol('A'))//false

bigint大数据值

const alsoHuge = BigInt(9007199254740991)//  9007199254740991n

综合练习

parseInt('12px') + parseInt('14px') +typeof parseInt(null)
//12 + 14 + typeof 'number'->26number
isNaN(Number(!!Number(parseInt("0.8"))))
//isNaN(Number!!(NUmber(0.8))) isNaN(有效数字) false
typeof !parseInt(null) + !isNaN(null)
// boolean true

let result = 10 + false + undefined + [] + 'yes' + null + true + {}
console.log(result)
// + 先找字符串([] {} ''),从头到字符前一个,数字转换相加,以后拼接字符串
//10+0+NaN=NaN+''+yes+null+true+'[object Object]'
//NaNyesnulltrue[object Object]


引用数据类型

对象数据类型object

  • {} 普通对象:任何一个对象都是由零到多组键值对(属性名:属性值)组成的(并且属性名不可以重复)
let person = {
    name:'丽丽',
    2:123
}

//无属性名
person.sex //undefined

//数字对象
person[2] //123
  • [] 数组对象:特殊对象数据类型,在中括号中设置属性值,属性名是默认从0开始递增的生成的数字,默认自动带length属性,存储数组长度
  • /^(\d|([1-9])?$/ 正则对象
  • Math 数据函数对象
  • 日期对象

函数数据类型function

函数就是一个方法或者一个功能体,实现某个功能的代码放到一起,进行封装,重复使用某个功能,直接调用函数即可=>封装=>减少页面冗余代码,提高代码重复使用率(低耦合,高内聚)

  • 创建函数
    • 形参
    • 返回值
  • 执行函数
    • 实参
  • arguments:函数内置的实参集合
    • 类数组集合,集合中存储着所有函数执行时,传递的实参信息
    • 不论是否设置形参,arguments都存在
    • 不论是否传递实参,arguments也都存在
    • arguments.callee:存储的是当前函数本身(JS严格模式下禁止使用)
  • 函数底层运行机制

任意数求和

假设存在函数sum,求多个值的和

  • 传递实参个数不确定
  • 传递的值数据类型不定(是否为有效数字)
  • 目的:把有效数字进行相加
function sum(){
    ...
}
sum(1,2)
sum(1,2,3)
sum(1,2,'a')
  • 使用arguments,查看参数。
function sum(n,m){
    console.log(arguments,n,m)
}
sum(1,2)
sum(1,2,3)
sum(1,2,'a')

arguments集合中存储着所有函数执行时,传递的实参信息,length为参数个数

实现sum函数

由上可知,非数字类型求和成了拼接字符串,需要控制参数类型

ES6 箭头函数实现,无数据类型校验

let sumES6 = (...args) => eval(args.join('+'))

数据类型关系

基本类型:按值操作(也叫值类型)

引用类型:操作堆类型地址(引用地址操作)

引用类型练习题

数组引用执行机制

let x = [10,20]
let y = x
let z = y
y = [30,40]
z[0] = 50
x[2] = 60
y[1] = 70
console.log(x,y,z)

let x = [10,20]y=[30,40]是新增,新增值新增引用地址创建堆,y[1]z[0]是修改,修改变量属性查询引用地址,修改堆属性值

连等于引用值

let m = { x:1} //->m->AAAFFF000->{x:1}
let n = m      //n->AAAFFF000
m.x = m = { x:2 } 
/** m.x={x:2}->mx.x=AAAFFF111->{x:2},
    AAAFFF000->{x:1,x:{x:2}},
    m->AAAFFF111->{x:2}
*/
console.log(m.x)//undefined

console.log(n) //{x:1,x:{x:2}}

堆的嵌套

let a = { n:1 }
let b = a
a.x=b
console.log(a)
//{n:1 x:{n:1,x{n:1,x:{...}}}}无限循环,形成了堆的嵌套,内存溢出

js 样式使用

猜测一下,每个div内文字的颜色是什么?

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>实战</title>
</head>
<body>
    <div id="box">颜色测试red</div>
    <div id="box-yellow">颜色测试yellow</div>
    <div id="box-blue">颜色测试blue</div>
    <script>
        let box=document.getElementById('box')
        let boxYellow=document.getElementById('box-yellow')
        let boxStyle=boxYellow.style
        boxStyle.color='red'
        let boxBlue=document.getElementById('box-blue')
        let boxStyleColor=boxBlue.style.color
        boxStyleColor='blue'
    </script>
</body>
</html>

代码执行效果

结果分析

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: 在JavaScript中,引用数据类型和基本数据类型在内存中的存储方式是不同的。基本数据类型存放在中,而引用数据类型存放在中。\[1\]当我们使用闭包时,JavaScript引擎会将闭包中的变量存储在内存中的\[\[scope\]\]中,以避免影响执行的执行。\[1\]基本数据类型的内存大小是固定的,而引用数据类型的大小是不固定的,取决于对象的属性和方法。\[2\]在访问引用数据类型时,我们首先得到的是对象在内存中的地址,然后按照这个地址去获取对象中的值,这就是按引用访问。而基本数据类型可以直接访问到其值。\[3\]在复制变量时,原始值会将其副本赋值给新变量,而引用值会将内存地址赋值给新变量,这意味着两个变量都指向内存中的同一个对象,对其中一个变量的修改会反映在另一个变量上。\[3\]在参数传递时,无论是原始类型还是引用类型,都是按值传递的。但是由于内存分配的差异,对于原始类型,只是将值传递给参数,互不影响;而对于引用类型,传递的是内存地址,因此对参数的修改会影响到原始对象。\[3\]所以,引用数据类型的存储以及访问、复制和参数传递方面与基本数据类型有所不同。 #### 引用[.reference_title] - *1* *2* [为什么基础数据类型存放在中,而引用数据类型存放在中?](https://blog.csdn.net/mhc20201554114/article/details/130028988)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [JavaScript中基本数据类型和引用数据类型的区别()](https://blog.csdn.net/qq_45684867/article/details/117380653)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值