javascript数据类型(三)

本篇主要介绍其他常用的对象(正则表达式比较特殊,单独放一章),然后对不同数据类型的存储结构进行归纳。

Date

常用的一些方法:

  • +new Date() // 获取当前时间戳
  • Date.now() // 获取当前时间戳
  • getTime() // 表示返回的毫秒数
  • getFullYear() // 返回四位数年份
  • getMonth() // 返回当前月份(0-11)
  • getDate() // 返回当前天数
  • getDay() // 返回当前星期几(0表示星期天,6表示星期六)
  • getHours()
  • getMinutes()
  • getSeconds()

项目过程中经常会使用momentjs和dayjs两个库进行和时间相关的处理,需要涉及时间的项目可以参考两个库的Api

Map,WeakMap,Set,WeakSet
1.Set

本身是一个构造函数,这个数据结构类似于数组,但是成员的值都是唯一的

所以对于简单的数组去重以及字符串去重,可以直接使用Set就可以完成

let s = new Set();
[1,2,3,5,2,2].forEach(x=>s.add(x))  // [1,2,3,5]
[...new Set(array)] // 数组去重
[...new Set(string)].join("")  // 字符串去重

Set函数可以接受一个数组,或者类似数组的对象作为参数

向 Set 加入值的时候,不会发生类型转换,所以5"5"是两个不同的值。Set 内部判断两个值是否不同,使用的算法叫做“Same-value-zero equality”,它类似于精确相等运算符(===),主要的区别是向 Set 加入值时认为NaN等于自身,而精确相等运算符认为NaN不等于自身,两个对象总是不相等的

将Set结构转化为数组:Array.from(s);

扩展运算符(...)内部使用for...of循环

Set的实例属性:1.constructor:构造函数;2.size,Set实例的成员总数,类似于数组的length

Set的方法:

1.操作方法

add(value),添加某个值,返回函数本身

delete(value),删除某个值,返回函数本身

has(value),判断成员中是否包含value,返回boolean

clear(),清除所有成员,没返回值

2.遍历方法

keys();返回键名的遍历器

values();返回键值的遍历器

entries();返回键值对的遍历器

forEach();使用回调函数遍历每个成员

Set 结构没有键名,只有键值(或者说键名和键值是同一个值),所以keys方法和values方法的行为完全一致。

2.WeakSet

WeakSet 结构与 Set 类似,也是不重复的值的集合。但是,它与 Set 有两个区别。

1.WeakSet 的成员只能是对象,而不能是其他类型的值

2.WeakSet 中的对象都是弱引用,即垃圾回收机制不考虑 WeakSet 对该对象的引用,也就是说,如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象还存在于 WeakSet 之中

垃圾回收机制何时运行是不可预测的,因此 ES6 规定 WeakSet 不可遍历。

1.操作方法

add(value),添加某个值,返回函数本身

delete(value),删除某个值,返回函数本身

has(value),判断成员中是否包含value,返回boolean
3.Map

Map类似于对象,本质上也是键值对的组合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。

如果对同一个键多次赋值,后面的值将覆盖前面的值,如果读取一个未知的键,则返回undefined

只有对同一个对象的引用,Map 结构才将其视为同一个键。Map 的键实际上是跟内存地址绑定的,只要内存地址不一样,就视为两个键。这就解决了同名属性碰撞(clash)的问题

1.属性:

size,返回Map结构的成员总数;

set(key, value),设置键名key对应的键值value,覆盖更新;

get(key),获取key对应的value,如果找不到key,返回undefined;

has(key),返回boolean;

delete(key),删除某个键,返回是否删除成功的boolean;

clear(),清除所有成员,没有返回值

2.遍历方法

keys(),返回键名的遍历器

values(),返回键值的遍历器

entries(),返回所有成员的遍历器

forEach(),遍历Map的所有成员

对象转为 Map 可以通过Object.entries()

4.WeakMap

WeakMap结构与Map结构类似,也是用于生成键值对的集合。区别有两点:

1.WeakMap只接受对象作为键名(null除外),不接受其他类型的值作为键名。

2.WeakMap的键名所指向的对象,不计入垃圾回收机制

如果你要往对象上添加数据,又不想干扰垃圾回收机制,就可以使用 WeakMap。一个典型应用场景是,在网页的 DOM 元素上添加数据,就可以使用WeakMap结构。当该 DOM 元素被清除,其所对应的WeakMap记录就会自动被移除。

WeakMap 弱引用的只是键名,而不是键值。键值依然是正常引用。

基本数据类型和引用类型的区别

到现在为止,基本数据类型和引用类型就总结的差不多了,在最后,要对两种类型进行总结。

数据类型的保存

之前说过,计算机程序运行过程中需要通过变量对值进行保存,js的变量是保存在栈内存中,值与值之间是独立存在的,修改其中一个值并不会改变其他值。

基本类型的值会直接在栈内存中储存,而引用类型会分为两部分,创建一个新的引用类型时,会开辟一个堆内存空间,将值保存在堆空间中,同时在栈内存中会存放一个指向堆内存的指针(相当于这个堆内存的门牌号和钥匙)。

浅拷贝和深拷贝

在这里插入图片描述

2.赋值:
基本数据类型:
var a = 123; var b = a;

第一步:给a分配一个栈内存
第二步:给b分配一个栈内存,将a中的数据拷贝出来
因此,基本数据类型赋值拷贝之后两个变量互相不影响
引用类型:
js var a = [qqq]; var b = a

第一步:分配一个堆内存,存储数据,分配一个栈内存,存储a对应的数据的堆内存地址(堆1),a可以根据地址找到相应的数据

第二步:给b分配一个栈内存,存储对应的堆内存地址(还是堆1),b也可以根据地址找到相应的数据。
当a或者b改变时,改变的是堆内存里面的数据,栈内存里的地址没有改变,因此引用类型赋值拷贝之后两个变量是相互影响的,一个变量改变会导致另一个变量的改变。

3.引用类型拷贝
如果想要对引用类型进行拷贝,使拷贝之后的结果互不影响的话,需要在拷贝时新增一个堆内存,将原始堆内存中的数据复制进去,同时新分配的栈内存存储新的堆内存地址。

4.深拷贝的方式
1.利用json进行转化

var a = JSON.stringify(b);
var c = JSON.parse(a); //将b拷贝给c

将b转化为字符串赋值给a,然后将a再转化为json赋予c
弊端:只能转化只有基础类型的对象,包含引用类型嵌套时不能使用

2.利用数组中的slice和concat方法

var a = ["1","2","3"];
var b = a.slice(0);
b[1] = "4"; //a = ["1","2","3"],b = ["1","4","3"]
var c = a.concat();
c[0] = "5"; //a = ["1","2","3"],c = ["5","2","3"]

弊端:无法切断引用类型嵌套时的关联,slice和concat类似

var aa = ["1",["1","2"],"3"];
var bb = aa.slice(0);
bb[1][1] = "33"; //aa=["1",["1","33"],"3"],此时嵌套的数据会被修改
bb[1] = "33"; //aa=["1",["1","33"],"3"],bb=["1", "33", "3"],此时嵌套的数据不会被修改

真正深拷贝需要深层遍历实现,lodash有cloneDeep方法,可以快速实现深拷贝

function deepClone(obj){
let cloneObj = {};
  if(obj===null) return obj;
  if(obj instanceof Date) return new Date(obj);
  if(obj instanceof RegExp) return new RegExp(obj);
  if(typeof obj !=='object') return obj;
  for(let i in obj){
    if(obj.hasOwnproperty(i)){
			cloneObj[i] = deepClone(obj[i])
    }
  }
  return cloneObj
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值