欢迎光临散文网 会员登陆 & 注册

【三】引用类型

2023-08-13 15:20 作者:驰骥  | 我要投稿



前言

本篇章主要介绍了引用类型的特点,诸如正则表达式、时间类型、基本包装类、Object、数组等,至于function部分,内容较多,将另起篇章。


面试回答

1.引用类型:引用类型有array、object、function。引用类型属于堆内存,占用的空间不固定,保存和复制的是指针。引用类型常用instanceof去判断,如果本身不知道数据属于什么类型的话,就用object.prototype.toString.call方法去判断,不管是instanceof还是call方法,他们本质上都是通过原型链判断。

2.数组去重:最常用的是利用Set这种数据结构,搭配Array.from或者扩展运算符来实现。至于其他方式,不管是利用indexOf、includes、sort(sort排序后相同的元素会相邻),首先都会有一层遍历。

3.深浅拷贝:深浅拷贝的区别在于,浅拷贝只复制指针,新旧对象仍使用同一块内存。而深拷贝会创建一个一模一样的对象,开辟新的内存,因此修改新对象不会影响原对象。简单点,就用JSON.parse包裹着JSON.stringify,这种方式算深拷贝,因为它开辟了新的内存空间,只不过JSON.stringify会丢失一些数据,比如undefined、function。准确点,就需要采取递归的方式去深拷贝,判断传入的数据是不是object,如果不是就抛出去,如果是那么就继续递归。

4.new关键字:new关键字先是创建新的对象,然后继承传入的函数原型,修改this指向并且执行构造函数,最后返回新的对象。


知识点

引用类型都是堆(heap) ,有两个特征:1. 保存和复制都是指针。2.占用空间不固定(大小不定),也不会自动释放,堆内存中。

1.RegExp

基本规则

关于RegExp对象还是经常会使用到,比如限制input输入框(校验邮箱是否符合)、匹配变量值做if判断等等。RegExp类型既可以通过字面量声明的方式创建,也可以通过new的方式创建;

字面量声明:/pattern/attributes ,例:let re1 = /ABC/g

new声明:new RegExp(pattern, attributes),例let regex=new RegExp('/abc/',g)

pattern既可以是正则表达式,也可以是字符串,如果是字符串,则如下:

attributes为可选的字符串 ,含属性 "g"、"i" 和 "m",分别用于指定全局匹配、不区分大小写的匹配和多行匹配

下面着重梳理几条规则,用来能够基本的识别正则表达式,具体属性可以参考:RegExp基础规则

1./ xxx /g ,所有的正则表达式均写在/ /内,反斜杠代表转义,如\d,表示数字

2.^表示行的开头,^\d表示必须以数字开头

$表示行的结束,\d$表示必须以数字结束

有头有尾则必须完全符合规则才可匹配,如^\d{3}$则表示,连续三个数字才可匹配。

3.[]表示能够匹配的范围,匹配的是单个字符

4.如果涉及特殊字符如'-',在正则表达式中,要用'\-'转义,如,/^\d{3}\-\d{3,8}$/

5.n{X,Y}表示至少出现X个连续n ,至多出现Y个连续n时,匹配。Y可不写。闭区间,含X,Y

6.*等于{0,} 即大于等于0次 ;+代表{1,} 即大于等于1次;?代表{0,1} 即0次或1次

7.用()表示的就是要提取的分组。比如:^(\d{3})\-(\d{3,8})$

8.取反:[^abc],查找任何不在方括号之间的字符。

根据上面8条规则来识别一下下述含义:

常用方法

RegExp 对象有 4 个方法:test()、exec() 、compile()、match()

test():test() 方法检索字符串中的指定值。返回值是 true 或 false。

match():match()方法返回值是符合规则的值(数组)。

exec():exec() 方法检索字符串中的指定值。返回值是被找到的值。如果没有发现匹配,则返回 null

compile():compile()方法用于改变 RegExp。

2.Date

定义

Date获取的时间为本地时间,即电脑或手机上的设备时间,如果你设备时间不准确,那么你获取的时间同样也会不准确;如若涉及时区问题,可以使用UTC时间 (零时区) 。

基础API

应用场景

1.针对要求高精确性的时间,举个例子:

假设:本地时间、服务器时间不一致,而这个假设发生的概率很大。

需求:一个案件需要点击拨打电话后才可提交案件

操作:点击拨打按钮记录的是本地时间(用来展示);提交案件记录的是服务器的时间(后端需要记录案件提交的时间);而这时候时间不一致会带来许多分析上的麻烦。比如你明明12:30:00(本地时间)打了电话,提交案件的时间却是12:00:00(服务器时间)。理论上提交案件的时间应该晚于拨打时间,却因为时间不一致,导致数据分析有异常。

解决办法:通过调用接口获取服务器时间,统一时间上的管理,避免造成数据分析的麻烦。

经验总结:如果涉及到时间问题,特别是对时间精确要求较高的需求时,需要考虑时间获取来源的统一。

2.针对时间格式的统一与转换

问题缘由:不同的浏览器对于new Date()的解析支持是不同的,比如ios就只支持"2021/12/12 12:21:21",而部分浏览器则只支持"2021-12-12 12:21:21"。而有时候需求对时间格式有着另外的要求,也需要对时间进行统一的处理。

经验总结:

首先,涉及到时间问题,首先要考虑时间格式能不能被识别兼容

其次,需要与后端统一好时间格式,避免由于时间格式产生的报错,诸如显示、转换等,推荐方法是前后端传值统一使用时间戳,时间格式由前端进行转换。

最后,涉及时间格式的转换,常见的便是new Date() 、elementUI中的dateTimepicker,而时间格式的转换我这边推荐插件moment.js或者dayjs或者自行封装一个简易的时间处理函数。

3.基本包装类型

本质

为了便于操作基本类型值,ECMAScript 还提供了3 个特殊的引用类型:Boolean、Number和String。而boolean、number、string基本类型之所以能够直接操作是因为在调用方法的过程中,默默进行基本包装类型的处理,如下:

相关知识点

装箱:基础类型-->引用类型

拆箱:引用类型-->基础类型

4.Object

属性的增强写法

JSON的理解

JSON是一种轻量级的数据交换格式,主要是为了跨平台交流数据用的,因此他的格式要求也相对规范严格,比如JSON的属性名必须有双引号,如果值是字符串,也必须是双引号。由于在请求接口中使用的JSON格式,所以对于前端代码中的入参基本都是通过序列化的方式进行入参的处理,如:

遍历方法

对象转数组

对象合并

5.Array

与Object的区别

1.数组有序,Object无序

2.数组的元素可以没有属性名(但是有索引),对象的元素必须有值

3.数组只能用整数作为数组元素的索引,而不能用字符串,且数组元素的使用只能通过方括号(arr[0])来获取

4.数组的空元素empty表示空位, 它不是一种数据类型, 而是由于人为修改arr.length 或者写入时多写了逗号造成的。empty和undefined在操作数组时的主要区别在于:使用数组的forEach()方法遍历时会自动忽略空位, 而使用for循环则会将empty转换为undefined并遍历。

Tip:使用对象或数组的方法前一定要先判断其是否存在,因为数组经常会连带方法使用,比如arr.indexOf('123'),此时如果arr不存在,那么程序会直接报错。

不修改原数组的方法

1、2:判断数组中是否包含一个元素3、4:找出第一个符合条件的数组成员5:判断数组是否为空,由于数组是对象,因此存在引用地址的问题,所以不能使用 arr === [] 来判断数组是否为空6、7:合并数组可以使用,不过6、7都属于浅拷贝,即仅适用于对不包含引用对象的一维数组的拷贝,就是对象不是那种多层嵌套的8:复制数组,不过8属于浅拷贝,即仅适用于对不包含引用对象的一维数组的拷贝,就是对象不是那种多层嵌套的9:适合用于将数组元素拼接后转换成字符串,但如果元素为undefined或null,它会被转换为空字符串。

修改原数组的方法

遍历方法

数组合并

数组去重

数组扁平化


应用

1.关键字

前端关键字有:delete、switch、case、default、break(跳出循环,map方法中不可用)、for、in、continue(跳出本次循环)、while、if、else、return(停止方法的执行)、try、catch、this、do、with、finally、throw、let、var、function、instanceof、typeof、new 等,这边挑选部分进行解释。

delete关键字

new关键字

接下来描述一些new操作符的的原理、过程及实现:

new操作符的作用是通过构造函数来创建一个实例对象,那么new操作符做的事包括:
1.创建新的对象
2.继承传入函数的原型
3.修改this指向并执行构造函数
4.返回新对象


PS:至于为什么不能写成let p = _new Person('Tom', 20)的形式,是因为_new是我们自定义的方法,需要以方法的形式调用;而let p = new Person(xxxx)之所以可以如此使用,是因为new是ECMA规定的内置语法,如果你非要写成_new Person()形式,就相当于新增了一个内置语法,等同于ES5升级到ES6

2.解构赋值

3.深浅拷贝

深浅拷贝的区别在于,浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。但深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。

具体表现即,深拷贝的数据与被拷贝对象完全没有关系,不管被拷贝对象如何改动,都不会影响深拷贝的数据;而浅拷贝的数据如果内层不嵌套,则与深拷贝的表现一致,如果内层嵌套,则被拷贝对象嵌套部分的数据修改会使拷贝对象同步修改。


4.类型判断

5.intanceof操作符的原理及实现


最后

走过路过,不要错过,点赞、收藏、评论三连~


【三】引用类型的评论 (共 条)

分享到微博请遵守国家法律