js的基本数据类型与引用数据类型
基本数据类型与引用数据类型
基本数据类型有五种
/*
基本数据类型有:
- String
- Number
- Boolean
- Null ** typeof null === 'object' 这只是js的遗留问题,null仍归属于普通数据类型
- Undefined
*/
var string = 'good'
var number = 123
var boolean = true
var nu11 = null
var undef1ned = undefined
引用数据类型有一种
/* 数组与对象都属于Object数据类型 */
var obj = {}
var arr = []
值传递在两种数据类型下的不同表现
var num = 123
var obj = {
numInObj: 456
}
/* 普通数据类型的值传递 */
var num2 = num
console.log(num) // 123
console.log(num2) // 123
num++
console.log(num) // 124
console.log(num2) // 123
num2++
console.log(num) // 124
console.log(num2) //124
/*
通过以上简单的尝试可以看到:
普通数据类型的值传递,就像克隆了一份原数据,新旧数据之间完全独立
它们的改变都不会影响到对方,这其实就是深拷贝
*/
/* 引用数据类型的值传递 */
var obj2 = obj
console.log(obj2.numInObj) // 456
obj.numInObj = 666
console.log(obj.numInObj) // 666
console.log(obj2.numInObj) // 666
obj.numInObj = 888
console.log(obj.numInObj) // 888
console.log(obj2.numInObj) // 888
/*
可以看到,引用数据类型的值传递,与普通类型的值传递大不同
引用数据类型的值传递的情况: 旧数据像是被人施加巫毒娃娃的效果
对巫毒娃娃的操作(新数据)也会作用到实体身上(旧数据),当然对旧数据
操作也会影响新数据
*/
由值传递结果的不同引发对两种数据类型的思考
通过以上的实验,两种数据类型的值传递情况是不一样的,那么导致这种结果的原因是啥呢?这里直接引出概念堆内存
与栈内存
。
我们在js中声明的所有变量,及变量所携带的数据都是存在内存中的,内存在内部分为堆内存
与栈内存
,而不同数据类型是存储在不同内存中的
基本数据类型的属性与属性值都是直接保存在栈内存中的
var num = 123
普通数据类型的值传递,就像克隆了一份原数据,新旧数据之间完全独立,它们的改变都不会影响到对方
var num = 123
var num2 = num
num = 666
console.log(num2) //123
num2 = 999
console.log(num) //666
引用数据类型,当然指的就是对象、数组这些。它们的储存就不是说单纯的储存在堆内存或者是栈内存中了,而是其属性名
保存在栈内存
中,属性值
保存在堆内存
中。此时有人就会想那怎么能够保持使得属性名对应正确的属性值呢?,答案就是,当我们申明一个对象时,会在堆内存
中开辟一个区域,区域有标识属于它的、唯一的内存地址值
。往后对象的所有数据都会储存在将这块区域中,而在栈内存
中的属性名
通过保存这个内存地址值
,就能正确找到对象和其中的数据了。
// 对象的字面量
var obj = {
name: 'Fitz',
age: 21
}
引用数据类型的值传递的情况: 旧数据像是被人施加巫毒娃娃的效果对巫毒娃娃的操作(新数据)也会作用到实体身上(旧数据),当然对旧数据操作也会影响新数据,最主要的原因就是,它们都指向同一块内存
// 对象的字面量
var obj = {
name: 'Fitz',
age: 21
}
var obj2 = obj
obj.name = 'lx'
console.log(obj.name) // lx
console.log(obj2.name) // lx