前言
这次面试发现自己的问题还是很多很多,最基础的js数组的问题都没有熟悉到位,面试官问js数组有哪些方法,我都回答不上来,还有就是很多知识都很零散,以前明明看过,但是就是容易忘,现在对今天面试的题目总结一下。
数组去重有哪些方法?
排序后遍历去重
let array = [1,22,44,44,44,33,33,33,33,44,22,1]
function deleteArray(){
let newArray = [];
array = array.sort()
array.map((index,item)=>{
if(index != array[item+1]){
newArray.push(index)
}
})
console.log(newArray)
}
deleteArray();//[1, 22, 33, 44]
说明:sort()方法比较特殊,会将[1,12,3,4,24]排序成[1,12,24,3,4],你会发现如果该数字是两位数的话,sort只会根据第一个数字排序,这样显然是错的,所以我们在进行排序的时候要在sort中传入一个比较函数,这也牵扯出了一道很容易考的题:
怎样实现一个随机数组(也称随机洗牌算法)?
arr = arr.sort(function(a,b){return Math.random() - 0.5;})//最好是针对数值型数组
分析:是的,你没有看错,一行代码就可以解决这个问题,只要在sort中放一个函数就可以,而且是不需要被调用的,根据函数返回值的正负,来判断怎么排序,具体参考这里。
indexof去重
let array = [1,22,44,44,44,33,33,33,33,44,22,1]
function deleteArray(){
let newArray = [];
for(let i = 0;i<array.length;i++){
if(newArray.indexOf(array[i]) == -1){
newArray.push(array[i])
}
}
console.log(newArray)
}
deleteArray();
set方法去重
let array = [1,22,44,44,44,33,33,33,33,44,22,1]
function deleteArray(){
let newArray = []
//使用set方法进行去重过后得到的是一个对象,所以我们还要想办法把它变成一个数组
newArray = new Set(array)
//Array.from可以直接将对象转换成数组,也可以使用...newArray的方法将可遍历对象转换成数组
newArray = Array.from(newArray)//或newArray = new Array(...newArray)
console.log(newArray)
}
deleteArray();//[1, 22, 33, 44]
使用reduce方法去重
参考这里
数组的方法有哪些?这些方法中不改变原数组的有哪些?
数组的方法有:
- concat:连接两个数组,不改变原数组
- join:将数组中的内容放入一个字符串中,括号中的参数就是分隔符,不改变原数组
-
slice:获取数组指定位置区间的元素,不改变原数组
- 不传参数时,相当于不操作,返回整个数组
- 传入一个参数时,会返回从该参数到数组末尾的所有元素
- 传两个参数时,会返回从第一个参数到第二个参数之间的所有元素,但是不包含最后一个元素
- 当传入的参数为负数时,会加上数组的长度再取元素,比如说slice(-2,-1)=>slice(3,4)(假设数组长度为5)
- 当传入两个参数,并且第一个参数大于第二个参数时,会返回空数组
- pop:删除并返回数组的最后一个元素,会改变原数组
- shift:从数组的头部删除元素,返回的是该元素,会改变原数组
- unshift:向数组的头部添加元素,返回的是数组长度,会改变原数组
- push:向数组的末尾添加一个元素,返回的是数组长度,会改变原数组
- reverse:将数组进行反转,返回的是反转后的数组,会改变原数组
- sort:对数组进行排序,原理是先将数组中的元素转换成字符串,然后比较字符串,如果要正确的排序,需要在方法中传入一个比较函数,返回的是排序后的数组,会改变原数组
-
splice:主要用途是在数组的中部插入或删除元素,返回的是从该数组中删除的元素,如果没有删除,则返回空数组,会改变原数组
- 删除任意数量的项,需要传入两个参数,第一参数指定删除的开始位置,第二个参数指定删除多少项
- 插入任意数量的项,需要传入3个参数,分别为起始位置,要删除的项数(一般取0),插入的项(可以为多项)
- 替换指定数目的项,参数和上面完全相同,只是第二个参数不再取0
-
indexOf:查找指定元素的位置,返回该元素第一次出现的位置,不会改变原数组
- 如果只传入一个参数,表明是查找该元素
- 如果传入两个参数,则第一个表示从哪个位置开始往后找,第二个参数表示要查找的元素
- lastIndexOf:从后往前查找指定元素的位置,只是和indexOf的查找方向不同,其他部分均相同
- reduce:这个方法很强大,也比较复杂,我专门总结了一篇文章,这个方法也不会改变原数组
总结:
改变原数组的方法有:shift,push,pop,unshift,sort,reserve,splice
不改变原数组的有:concat,join,slice,reduce,indexOf,lastIndexOf
http常见状态码有哪些?服务器怎么判断出是否应该返回304状态码?
答:常见的状态码就先不说了,这篇文章中写了,重点看服务器怎么判断应该返回304状态码,具体实现为:
- 浏览器第一次请求资源,响应成功,会返回200,然后浏览器会将这个资源的副本缓存在本地;(这个资源的响应头部会带有一个ETag字段,用来标志这个资源)
- 下次再发送请求时,在请求头中会有一个If Modified Since字段,这个字段是告诉服务器如果在这个时间之后的资源没有发生更改,自己就可以直接从缓存中拿了,如果有更改,就需要发送新的资源了;(服务器就是通过ETag字段来判断资源是否更改)
- 服务器通过匹配ETag字段发现没有更改时,会返回一个304。
js中的事件冒泡和事件捕获
答:事件冒泡是IE的事件流,事件开始是由最具体的元素接收,然后逐步向上级传播为较不具体的节点;而事件捕获是网景推出的事件流,和事件冒泡刚好相反,事件捕获是从外到内,从最不具体的流向具体的节点,也就是最具体的节点是最后接收到事件的。(补充:DOM2级事件的流的三个阶段跟别为事件捕获阶段,处于目标阶段,事件冒泡阶段)
js中基本数据类型有哪些?引用类型有哪些?
答:基本数据类型包括:null,undefined,string,number,boolean,symbool(es6中新增);
引用类型只有Object;其中基本数据类型是存放在栈中,引用数据类型是存放在堆中。
null和undefined的区别?
答:null通常表示指向空指针的对象,而undefined一般是表示只进行声明但是没有初始化的变量。
将null和undefined转换成number类型返回的是什么?
答:Number(null)==0 Number(undefined)==NaN Number("")==0
将哪些转换成布尔类型会返回false?
答:false,NaN,"",null,undefined,0
js事件循环机制?
答:事件循环机制就是任务分为主任务和异步任务,只有在主任务都执行完毕后才会去异步队列中取异步任务执行,这样就会造成异步的假象。具体解释,可以参考这里。
js中的微任务有哪些?
答:微任务有process.nextTick和promise.then
call()和apply()以及bind()的区别?
答:首先三者都可以绑定this,从而改变this的指向,区别在于call()和apply()只是绑定this指向,没有返回值;而使用bind()时,会返回一个函数,绑定了this指向后的这个函数在任何地方进行调用this都不会发生改变。而call和apply之间的区别在于前者传参时是逐个传入,而后者是传入一整个数组。
数组进行遍历的方法有哪些?它们的区别在哪儿?
答:遍历数组的方法有:
- for -- 需要知道数组的长度
- forEach -- 不需要数组的长度,没有返回值
- map -- 返回每次函数调用的结果组成的数组,不改变原数组
- some -- 只要函数调用结果有一个返回true,结果就是true
- every -- 函数调用的结果全部返回true时,返回的就是true
- filter -- 根据条件对数组元素进行筛选,返回的是满足条件的元素组成的数组,不会改变原数组
- reduce -- 为数组中的每个元素执行一个回调函数,上面也有提到。
- for-of -- 用来遍历可迭代的数据结构,比如说数组,字符串,集合,类数组对象等。
遍历对象的方法有:
- for-in -- 返回可枚举属性(包括自身和继承的),也可以遍历数组,不过返回的是数组的下标
- Object.getOwnPropertyNames -- 返回该对象自身的所有属性(包括可枚举的和不可枚举的)组成的数组
- Object.keys -- 返回该对象的自身的可枚举属性组成的数组
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。