js基础复习–变量类型和计算
基本类型(值类型)和引用类型
一、首先要明确值类型和引用类型有哪些
1.值类型:String、Number、Boolean、undefined、null、symbol
2.引用类型:object、array、function
二、两种类型的判断方法
let a = [1,2,3]
function b(params) {
console.log(1)
}
let c= 1;
let d={
obj:520
}
let e = 'string'
let f= true
console.log(typeof(a))//object
console.log(typeof(b))//function
console.log(typeof(c))//number
console.log(typeof(d))//object
console.log(typeof(e))//string
console.log(typeof(f))//boolean
console.log(typeof(undefined))//undefined
console.log(typeof(null))//object
在使用typeof的时候,除了null之外的基本值类型,都可以正确判断其类型,而引用类型和null则需要注意,对象和数组以及null结果都会显示是object,而functtion就是显示为function。有人会说instanceof可以,但是这对基本类型来说存在着问题,因为该方法其内部机制就是通过原型链来判断的。正确方法就是使用Object.prototype.slice.call(需要判断的对象),如:
三、值类型和引用类型的区别
1.存储的位置不一样:基本数据类型是存放在栈区的,如果在一个函数中声明一个值类型的变量,那么这个变量当函数执行结束之后会自动销毁;引用数据类型同时保存在栈区和堆区,是因为引用类型一般有键值对组成,key就存储在栈区,然后对应的值就是引用地址,这个地址就作为堆区的key值,指向引用类型的值,引用类型的变量不会自动销毁,当没有引用变量引用它时,系统的垃圾回收机制会回收它;如图:
a.基本类型存储:
b.引用类型存储:
简而言之,基本类型和引用类型的赋值是不同的,基本类型是浅拷贝,引用类型是深拷贝。出现这种差别的原因是因为基本类型一般占用空间小,存取速度快也比较频繁,赋值的时候对dom的操作以及一些性能影响不是很大,但是引用类型不同,一般程序中使用的对象或者方法函数比较大,代码量比较大,自然存储的空间也相应的增大,而堆的占据空间也比较大符合特点,如果是按照基本类型的方法存储的话,复制就会比较慢,对性能要求较高,所以采用这种方法来对引用类型存储,是对cpu和内存的综合考虑。
2.比较的区别:
基本数据类型的比较是值的比较,引用类型的比较是引用的比较,比较对象的内 存地址是否相同;
3.添加方法的区别:
值类型无法添加属性和方法,引用类型可以添加属性和方法,基本数据类型的值是不可变的,任何方法都无法改变一个基本类型的值,当这个 变量重新赋值后看起来变量的值是改变了,但是这里变量名只是指向变量的一个 指针,所以改变的是指针的指向改变,该变量是不变的,但是引用类型可以改变。
如:
结果都是undefined;
结果person.age=18,person.eat返回一个函数;
3.深拷贝
/**
* 深拷贝
* @param {Object} obj 要拷贝的对象
*/
function deepClone(obj = {}) {
if (typeof obj !== 'object' || obj == null) {
// obj 是 null ,或者不是对象和数组,直接返回
return obj
}
// 初始化返回结果
let result
if (obj instanceof Array) {
result = []
} else {
result = {}
}
for (let key in obj) {
// 保证 key 不是原型的属性,
//就是不要复制对象原型链上的东西,保证要复制的东西是它自己有的
if (obj.hasOwnProperty(key)) {
// 递归调用,解决多级对象\数组
result[key] = deepClone(obj[key])
}
}
// 返回结果
return result
}