2021-10-05

常见前端面试题答案汇总
1.css的居中方式
1.1 内联元素水平居中
利用 text-align: center 可以实现在块级元素内部的内联元素水平居中.此方法对内联元素(inline), 内联块(inline-block), 内联表(inline-table), inline-flex元素水平居中都有效.
代码如下:

center-text{
Text-aling:center;
}

1.2 块级元素水平居中
通过把固定宽度块级元素的margin-left和margin-right设成auto,就可以使块级元素水平居中.
核心代码:

center-block{ 
margin: 0 auto;
}

1.3 多块级元素水平居中
1.3.1 利用inline-block
如果一行中有两个或两个以上的块级元素,通过设置块级元素的显示类型为inline-block和父容器的text-align属性从而使多块级元素水平居中.
核心代码:

.container {
    text-align: center;
}
.inline-block {
    display: inline-block;
}

1.3.2 利用display: flex
利用弹性布局(flex),实现水平居中,其中justify-content 用于设置弹性盒子元素在主轴(横轴)方向上的对齐方式,本例中设置子元素水平居中显示.
核心代码:

flex-center {
    display: flex;
    justify-content: center;
}

2 垂直居中
2.1 单行内联(inline-)元素垂直居中
通过设置内联元素的高度(height)和行高(line-height)相等,从而使元素垂直居中.
核心代码:

#v-box {
    height: 120px;
    line-height: 120px;
}

2.2 多行元素垂直居中
2.2.1 利用表布局(table)
利用表布局的vertical-align: middle可以实现子元素的垂直居中.
核心代码:

.center-table {
    display: table;
}
.v-cell {
    display: table-cell;
    vertical-align: middle;
}

2.2.2 利用flex布局(flex)
利用flex布局实现垂直居中,其中flex-direction: column定义主轴方向为纵向.因为flex布局是CSS3中定义,在较老的浏览器存在兼容性问题.
核心代码:

.center-flex {
    display: flex;
    flex-direction: column;
    justify-content: center;
}

2.2.3 利用“精灵元素”
利用“精灵元素”(ghost element)技术实现垂直居中,即在父容器内放一个100%高度的伪元素,让文本和伪元素垂直对齐,从而达到垂直居中的目的。
核心代码:

.ghost-center {
    position: relative;
}
.ghost-center::before {
    content: " ";
    display: inline-block;
    height: 100%;
    width: 1%;
    vertical-align: middle;
}
.ghost-center p {
    display: inline-block;
    vertical-align: middle;
    width: 20rem;
}

2.3 块级元素垂直居中
2.3.1 固定高度的块级元素
我们知道居中元素的高度和宽度,垂直居中问题就很简单.通过绝对定位元素距离顶部50%,并设置margin-top向上偏移元素高度的一半,就可以实现垂直居中了.
核心代码:

.parent {
  position: relative;
}
.child {
  position: absolute;
  top: 50%;
  height: 100px;
  margin-top: -50px;
}

2.3.2 未知高度的块级元素
当垂直居中的元素的高度和宽度未知时,我们可以借助CSS3中的transform属性向Y轴反向偏移50%的方法实现垂直居中.但是部分浏览器存在兼容性的问题.
核心代码:

.parent {
    position: relative;
}
.child {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
}

3 水平垂直居中
3.1 固定宽高元素水平垂直居中
通过margin平移元素整体宽度的一半,使元素水平垂直居中.
核心代码:

.parent {
    position: relative;
}
.child {
    width: 300px;
    height: 100px;
    padding: 20px;
    position: absolute;
    top: 50%;
    left: 50%;
    margin: -70px 0 0 -170px;
}

3.2 未知宽高元素水平垂直居中
利用2D变换,在水平和垂直两个方向都向反向平移宽高的一半,从而使元素水平垂直居中.
核心代码:

.parent {
    position: relative;
}
.child {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

3.3 利用flex布局
利用flex布局,其中justify-content 用于设置或检索弹性盒子元素在主轴(横轴)方向上的对齐方式;而align-items属性定义flex子项在flex容器的当前行的侧轴(纵轴)方向上的对齐方式.
核心代码:

.parent {
    display: flex;
    justify-content: center;
    align-items: center;
}

3.4 利用grid布局
利用grid实现水平垂直居中,兼容性较差,不推荐.
核心代码:

.parent {
  height: 140px;
  display: grid;
}
.child {
  margin: auto;
}

3.5 屏幕上水平垂直居中
屏幕上水平垂直居中十分常用,常规的登录及注册页面都需要用到,要保证较好的兼容性,还需要用到表布局.
核心代码:

.outer {
    display: table;
    position: absolute;
    height: 100%;
    width: 100%;
}
.middle {
    display: table-cell;
    vertical-align: middle;
}
.inner {
    margin-left: auto;
    margin-right: auto;
    width: 400px;
} 

2.px,em,rem,%
== 1.px(像素)
px单位的名称为像素,它是一个固定大小的单元,像素的计算是针对(电脑/手机)屏幕的,一个像素(1px)就是(电脑/手机)屏幕上的一个点,即屏幕分辨率的最小分割。由于它是固定大小的单位,单独用它来设计的网页,如果适应大屏幕(电脑),在小屏幕(手机)上就会很不友好,做不到自适应的效果。
2.em(相对长度单位)
em单位用的也比较多,特别是国外;em单位的名称为相对长度单位,它是用来设置文本的字体尺寸的,相对于父级元素对象内文本的字体尺寸;如果没有人为设置当前对象内文本的字体尺寸,那么它相对的是浏览器默认的字体尺寸(16px)。
3.rem(css3新增的相对长度单位)
rem是css3新增的一个相对长度单位,它的出现是为了解决em的缺点,em可以说是相对于父级元素的字体大小,当父级元素字体大小改变时,又得重新计算。rem出现就可以解决这样的问题,rem只相对于根目录,即HTML元素。所以只要在html标签上设置字体大小,文档中的字体大小都会以此为参照标准,一般用于自适应布局。
4.%(百分比)
%也很常见,它和em差不多一样,都是相对于父级元素。但%可以在很多属性中使用,比如:width、height、font-size等。而em是用来设置字体大小(font-size)的单位,width、height等属性是没有em单位的。
px、em、rem和%的区别与总结:
1.px是固定长度单位,不随其它元素的变化而变化;
2.em和%是相对于父级元素的单位,会随父级元素的属性(font-size或其它属性)变化而变化;
3.rem是相对于根目录(HTML元素)的,所有它会随HTML元素的属性(font-size)变化而变化;
4.px和%用的比较广泛一些,可以充当更多属性的单位,而em和rem是字体大小的单位,用于充当font-size属性的单位
5.一般来说:1em = 1rem = 100% = 16 px ==

3.display的值和作用
在这里插入图片描述
4.路由跳转的方式
1.router-link
1.不带参数

<router-link :to="{name:'home'}">
<router-link :to="{path:'/home'}">`

//name,path都行, 建议用name
// 注意:router-link中链接如果是’/‘开始就是从根路由开始,如果开始不带’/’,则从当前路由开始。
2.带参数

<router-link :to="{name:'home', params: {id:1}}">

// params传参数 (类似post)
// 路由配置 path: “/home/:id” 或者 path: “/home:id”
// 不配置path ,第一次可请求,刷新页面id会消失
// 配置path,刷新页面id会保留
// html 取参 r o u t e . p a r a m s . i d / / s c r i p t 取 参 t h i s . route.params.id // script 取参 this. route.params.id//scriptthis.route.params.id

<router-link :to="{name:'home', query: {id:1}}">

// query传参数 (类似get,url后面会显示参数)
// 路由可不配置
// html 取参 r o u t e . q u e r y . i d / / s c r i p t 取 参 t h i s . route.query.id // script 取参 this. route.query.id//scriptthis.route.query.id
2. this. r o u t e r . p u s h ( ) ( 函 数 里 面 调 用 ) 1. 不 带 参 数 t h i s . router.push() (函数里面调用) 1.不带参数 this. router.push()()1.this.router.push(’/home’)
this. r o u t e r . p u s h ( n a m e : ′ h o m e ′ ) t h i s . router.push({name:'home'}) this. router.push(name:home)this.router.push({path:’/home’})
2.query传参
this. r o u t e r . p u s h ( n a m e : ′ h o m e ′ , q u e r y : i d : ′ 1 ′ ) t h i s . router.push({name:'home',query: {id:'1'}}) this. router.push(name:home,query:id:1)this.router.push({path:’/home’,query: {id:‘1’}})
// html 取参 r o u t e . q u e r y . i d / / s c r i p t 取 参 t h i s . route.query.id // script 取参 this. route.query.id//scriptthis.route.query.id
3. params传参
this.$router.push({name:‘home’,params: {id:‘1’}}) // 只能用 name
// 路由配置 path: “/home/:id” 或者 path: “/home:id” ,
// 不配置path ,第一次可请求,刷新页面id会消失
// 配置path,刷新页面id会保留
// html 取参 r o u t e . p a r a m s . i d / / s c r i p t 取 参 t h i s . route.params.id // script 取参 this. route.params.id//scriptthis.route.params.id
4. query和params区别
query类似 get, 跳转之后页面 url后面会拼接参数,类似?id=1, 非重要性的可以这样传, 密码之类还是用params刷新页面id还在
params类似 post, 跳转之后页面 url后面不会拼接参数 , 但是刷新页面id 会消失
3. this. r o u t e r . r e p l a c e ( ) ( 用 法 同 上 , p u s h ) 4. t h i s . router.replace() (用法同上,push) 4. this. router.replace()(,push)4.this.router.go(n) ()
this. r o u t e r . g o ( n ) 向 前 或 者 向 后 跳 转 n 个 页 面 , n 可 为 正 整 数 或 负 整 数 p s : 区 别 t h i s . router.go(n) 向前或者向后跳转n个页面,n可为正整数或负整数 ps : 区别 this. router.go(n)nnps:this.router.push
跳转到指定url路径,并想history栈中添加一个记录,点击后退会返回到上一个页面
this. r o u t e r . r e p l a c e 跳 转 到 指 定 u r l 路 径 , 但 是 h i s t o r y 栈 中 不 会 有 记 录 , 点 击 返 回 会 跳 转 到 上 上 个 页 面 ( 就 是 直 接 替 换 了 当 前 页 面 ) t h i s . router.replace 跳转到指定url路径,但是history栈中不会有记录,点击返回会跳转到上上个页面 (就是直接替换了当前页面) this. router.replaceurlhistory()this.router.go(n)
向前或者向后跳转n个页面,n可为正整数或负整数

5.vue生命周期的理解在这里插入图片描述

6.数组去重
1.利用ES6 Set去重(ES6中最常用)

function unique (arr) {
  return Array.from(new Set(arr))
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
//[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {}, {}]

不考虑兼容性,这种去重的方法代码最少。这种方法还无法去掉“{}”空对象,后面的高阶方法会添加去掉重复“{}”的方法。
2.利用for嵌套for,然后splice去重(ES5中最常用)

function unique(arr){            
	for(var i=0; i<arr.length; i++){
		for(var j=i+1; j<arr.length; j++){
	        if(arr[i]==arr[j]){         //第一个等同于第二个,splice方法删除第二个
	            arr.splice(j,1);
                j--;
            }
        }
    }
return arr;
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
//[1, "true", 15, false, undefined, NaN, NaN, "NaN", "a", {…}, {…}] //NaN和{}没有去重,两个null直接消失了  

3.利用indexOf去重

function unique(arr) {
	 if (!Array.isArray(arr)) {
		 console.log('type error!')
         return
    }
    var array = [];
    for (var i = 0; i < arr.length; i++) {
		 if (array .indexOf(arr[i]) === -1) {
		 	array .push(arr[i])
         }
    }
    return array;
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
 // [1, "true", true, 15, false, undefined, null, NaN, NaN, "NaN", 0, "a", {…},{…}]  //NaN、{}没有去重 

新建一个空的结果数组,for 循环原数组,判断结果数组是否存在当前元素,如果有相同的值则跳过,不相同则push进数组。(个人认为对于初学者来讲这是目前最易懂的方法)
4.利用sort()

function unique(arr) {
	 if (!Array.isArray(arr)) {
     console.log('type error!')
     return;
}
arr = arr.sort()
var arrry= [arr[0]];
for (var i = 1; i < arr.length; i++) {
	 if (arr[i] !== arr[i-1]) {
	 arrry.push(arr[i]);
	 }
}
return arrry;
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
// [0, 1, 15, "NaN", NaN, NaN, {…}, {…}, "a", false, null, true, "true", undefined]      //NaN、{}没有去重

利用sort()排序方法,然后根据排序后的结果进行遍历及相邻元素比对。
5.利用对象的属性不能相同的特点进行去重

function unique(arr) {
	if (!Array.isArray(arr)) {
	console.log('type error!')
	return
}
var arrry= [];
var  obj = {};
for (var i = 0; i < arr.length; i++) {
	if (!obj[arr[i]]) {
		arrry.push(arr[i])
		obj[arr[i]] = 1
	} else {
		obj[arr[i]]++
	}
}
return arrry;
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
//[1, "true", 15, false, undefined, null, NaN, 0, "a", {…}]    //两个true直接去掉了,NaN和{}去重

6.利用includes

function unique(arr) {
	if (!Array.isArray(arr)) {
	console.log('type error!')
	return
	}
	var array =[];
	for(var i = 0; i < arr.length; i++) {
		if( !array.includes( arr[i]) ) {//includes 检测数组是否有某个值
		array.push(arr[i]);
		}
	}
	return array
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
//[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}, {…}]     //{}没有去重

7.利用hasOwnProperty

function unique(arr) {
	var obj = {};
	return arr.filter(function(item, index, arr){
	return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true)
	})
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
//[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}]   //所有的都去重了

利用hasOwnProperty 判断是否存在对象属性
8.利用filter

function unique(arr) {
	return arr.filter(function(item, index, arr) {
	//当前元素,在原始数组中的第一个索引==当前索引值,否则返回当前元素
		return arr.indexOf(item, 0) === index;
	});
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
//[1, "true", true, 15, false, undefined, null, "NaN", 0, "a", {…}, {…}]

9.利用递归去重

function unique(arr) {
	var array= arr;
	var len = array.length;
	array.sort(function(a,b){   //排序后更加方便去重
	return a - b;
	})
function loop(index){
	if(index >= 1){
		if(array[index] === array[index-1]){
		array.splice(index,1);
		}
	loop(index - 1);    //递归loop,然后数组去重
	}
}
loop(len-1);
return array;
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
//[1, "a", "true", true, 15, false, 1, {…}, null, NaN, NaN, "NaN", 0, "a", {…}, undefined]

10.利用Map数据结构去重

function arrayNonRepeatfy(arr) {
	let map = new Map();
	let array = new Array();  // 数组用于返回结果
	for (let i = 0; i < arr.length; i++) {
		if(map .has(arr[i])) {  // 如果有该key值
		map .set(arr[i], true); 
		} else { 
		map .set(arr[i], false);   // 如果没有该key值
		array .push(arr[i]);
		}
	} 
	return array ;
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
//[1, "a", "true", true, 15, false, 1, {…}, null, NaN, NaN, "NaN", 0, "a", {…}, undefined]

创建一个空Map数据结构,遍历需要去重的数组,把数组的每一个元素作为key存到Map中。由于Map中不会出现相同的key值,所以最终得到的就是去重后的结果。

11.利用reduce+includes

function unique(arr){
	return arr.reduce((prev,cur) => prev.includes(cur) ? prev : [...prev,cur],[]);
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr));
// [1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}, {…}]

12.[…new Set(arr)]

[...new Set(arr)] //代码就是这么少----(其实,严格来说并不算是一种,相对于第一种方法来说只是简化了代码)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值