前端面试题总结 2019---持续更新

题目来自于https://www.jianshu.com/p/eb0f269098d5以及来自个人的整理,答案是参考不同的资料写的,会不断完善。

题目是目前前端的一些核心知识点,即使不面试,复习一下也很好。

 

【CSS篇】

1. CSS盒子模型,绝对定位和相对定位

盒模型比较全面的理解:https://www.cnblogs.com/clearsky/p/5696286.html
盒模型即box model,其包含content,padding,border,margin。元素实际占有的总宽度包含这些所有。而默认的盒模型标准(box-sizing:content-box),只认定内容部分为width,为了方便计算,一般在初始会reset 为:box-sizing:border-box.此时设定的宽度包含了border在内的所有部分。

绝对定位:相对于最近的已经定位的元素进行定位;脱离文档流。如果没有最近的定位元素,则相对于body.

相对定位:相对自身定位;不脱离文档流。

固定定位:相对于浏览器窗口;脱离文档流。

 2.清除浮动,什么时候需要清除浮动,清除浮动都有哪些方法。

清除浮动详解,这篇解释清晰:https://www.jianshu.com/p/5a7854a73298

浮动可以满足我们需要的布局,即元素在左右位置排列,但会造成影响。因为其浮动后,脱离了原来的文档流,父元素会出现高度坍塌。

清除浮动常用方法:

(1)伪元素,使父元素默认还有一个元素,并且给伪元素添加clear:both,即此元素的左右两边均不允许出现浮动元素,此元素会位于浮动元素的下方,从而使父元素被撑开。

.fixed::afer{

         content:'';

         display:table;

         clear:both;

}

(2) 父元素设置:overflow:hidden;其本质是将父元素变为BFC块级格式化上下文,其高度包含浮动元素。

 3. 浮层水平垂直居中

https://www.imooc.com/article/17652?block_id=tuijian_wz

1) flex布局

.parent{
    width:100%;
    display:flex;
    justify-content:center;//水平
    align-items:center;//垂直
}
.children{
    width:100px;
    height:100px;
    ...
}

2) 绝对定位

.parent{
    position:abosolute;
    width:100%;
    height:100%;
    ...
}
.children{
    width:100px;
    height:100px;
    position:absolute;
    top:50%;
    left:50%;
    transform:translate(-50%,-50%);
}

3)定位+margin:auto

.parent{
    width:100%;
    position:relative;
}
.child{
    width:100px;
    height:100px;
    position:absolute;
    top:0;
    left:0;
    bottom:0;
    margin:auto;
}

 

 4. display的取值和用法

这里列举较常用的,实际很多;

display:none;元素不被显示

display:block;块级元素,前后有换行符

display:inline;内联元素,前后无换行符

display:inline-block;行内块

display:table;块级表格,类似表格,前后换行符

可以通过document.getElementById().style.display进行设置

 

5. 选择器优先级,样式冲突时,如何解决。

内联样式要高于style中的样式, 引入的样式文件优先级最低。

!important 要高于其它选择器的各种组合。权重上 #id为100,.class为10,元素本身为 1,选择器的权重最大者,样式冲突时,则会优先选择其样式。权重相同时,就近选择样式。

 6.对动画有何了解,canvas和svg的区别,CSS3新增伪类有哪些

Css3动画http://www.w3school.com.cn/css3/css3_animation.asp

animation属性,可以设置动画的 animation-name,animation-duration,animation-timing-function,animation-delay,animation-iteration-count,animation-direction.

使用@keyframes定义动画的名字以及在某个时间点该元素的样式,(可以定义时间0~100%中的任意点)

如下 @keyframes animationName{

         0%: {},

        100%:{}

}

canvas和svg的区别:canvas 使用javascript进行绘制,所有绘制在js中实现,其内部图形没有DOM概念,无法绑定事件,适合图像密集型游戏,依赖于分辨率;svg是基于xml绘制,每个图形元素都是一个DOM,可以绑定事件,不依赖于分辨率,其在放大或是改变尺寸情况下,图像清晰度不变。

新增伪类举例::nth-child,:only-child, :first-of-type; :last-of-type

 7. px, em, rem, %的区别, CSS中link和@import的区别

px是像素,一般是固定大小,em,相对于其父元素设置的font-size,若未设置,则为16px,

 rem是相对于根元素的font-size,若未设置,则为16px;设置方法为document.documentElement.style.fontSize,

%是相对于父元素的尺寸的百分比。

link写在html中:<link href="style.css"  ref="stylesheet" type="text/css">

@import写在style,或css文件中, @import(style.css)

 

8.了解过Flex吗?

基本上会参考这里:http://www.runoob.com/w3cnote/flex-grammar.html 其中,还有参考文章,需要深入了解的应多加练习。

flex组要是进行页面的布局,未来会成为较主要的布局方式。

在父元素设置 display:flex属性之后,其子元素的float,vertical-align,clear属性将失效。

比如说设置子元素在父元素中水平居中,在其父元素中指定justify-content:center,垂直居中:align-items:center;align-items定义其在交叉轴上的位置关系。在这之前,同flex-direction,来指定主轴是水平还是垂直。

flex属性较多,需要练习中积累注意。

 

 Javascript篇

1. Javascript里有哪些数据类型,解释清楚null 和 undefined,解释清楚原始类型和引用数据类型。

有原始数据类型和对象类型,原始类型又包含number,string,boolean,null,undefind。 undefined就是这个变量没有值,比如这个变量定义了,却没有赋值;null则是将变量的值清空。可以先定义一个变量,给其赋值为null。引用类型的值是对象,js不允许直接操作对象的内存空间,实际是操作其引用。定义引用类型的变量,实际上的值是指向对象的指针。

 2.prototype是什么,怎么理解原型链。

prototype称之为对象的原型。每个javescript对象(null除外)都会和另一个对象相关联,这个另一个对象就是“原型”,每个对象都从“原型”继承属性。比如,{},其就可以从Object.Prototype中继承属性。对于原型链,形成一系列链接的原型对象,就是原型链。比如new Array() 创建的对象的原型是Array.prototype。其又继承自Object.prototype.这就形成了链接。

从构造函数和原型对象的角度来讲。构造函数中有一个属性是prototype,指向原型对象,共有的属性会写在原型对象中。实例有一个属性__proto__指向其原型对象,原型对象本身也有属性__proto__指向其原型,这样就形成了原型链

 3.函数的this是什么含义,什么情况,怎么用?

https://blog.csdn.net/qq_33988065/article/details/68957806

1. 全局作用域或者是普通函数中的this,指向全局对象window。

2.方法调用时,谁调用指向谁。

//对象调用 var person={ run:function(){console.log(this)}}; person.run() // person

//事件绑定 btn.οnclick=function(){console.log(this)}//btn

3.构造函数中的this指向未来构造函数创造的实例

4.箭头函数 this,指向外层作用域。箭头函数的作用就是统一内外层作用域,无需担心this指向其它。

4. apply 和 call的用处

让函数能够在某个指定的对象下运行。

如:

var obj={x:1};

function foo(){console.log(this.x));

foo.call(obj)//结果为1

call,apply第一个参数,都是运行函数的作用域,第二个call接受的是一个一个的参数,apply是数组。

https://blog.csdn.net/caseywei/article/details/81746953

https://www.cnblogs.com/ly0612/p/6821124.html

 

 5.数组和对象有哪些原生方法(操作数据)

/****数组中添加和删除*****/
//1)push:在数组的末尾增加一个或多个元素
var a=[];
a.push("thanks");
console.log(a); // [ 'thanks' ]
a.push("one","two");
console.log(a); // [ 'thanks', 'one', 'two' ]
//2)pop:删除数组最后一个元素,减小长度并返回它删除的值
a.pop()
console.log(a);//[ 'thanks', 'one' ]



//3) Array.join() 将数组中的元素都转化成字符串并通过某字符连接起来,返回生成的字符串。
//不指定分隔符时默认为此操作不改变原数组
a=[1,2,3];
var b=a.join('-');
console.log(b);//1-2-3
console.log(a)//[1,2,3]


//4)Array.reverse()  将原数组颠倒顺序
b=a.reverse();
console.log(b);//[3,2,1]

/**********排序***** */

//5) array.sort()  将数组元素按照字母表顺序进行排序,
a=['banana','apple','cherry'];
b=a.sort();
console.log(b);//[ 'apple', 'banana', 'cherry' ]
//5.1) 讲数组元素按照数值大小进行排序
a=[33,1,3,23];
b=a.sort((a,b)=>(a-b))
console.log(b) //[ 1, 3, 23, 33 ]
//5.2)不区分大小写的按照字母表顺序进行排序
a=['ant','Dog','Bug','cat'];
b=a.sort((s,t)=>{
    var a=s.toLowerCase();
    var b=t.toLowerCase();
    if (a<b) return -1;
    if (a>b) return 1;
    return 0
})
console.log(b)  // [ 'ant', 'Bug', 'cat', 'Dog' ]


//6)array.concat()数组连接
a=[1,2];
b=[4,5,6];
var c=[7];
var d=a.concat(b);
var e=a.concat(b,c)

console.log(d,e)//[ 1, 2, 4, 5, 6 ] [ 1, 2, 4, 5, 6, 7 ]

//7)slice选取数组中的一个片段 arr.splice(m,n),选取(m,n-1)这几个元素,如果没有n,则默认到末尾
a=[1,2,3,4,5,6,7];
b=[1,2,3,4,5,6,7];
c=a.slice(2,4)
console.log(c)//[3,4]
d=b.slice(2)
console.log(d)//[3,4,5,6,7]



/********splice删除/插入数组,原数组被改变********* */
//array.splice()第一个参数表示开始删的位置,第二个参数是删几个,后面的参数可选,有的话则插入到被删的位置
a=[1,2,3,4,5];
b=a.splice(1,3) 
console.log(a,b) //[ 1, 5 ] [ 2, 3, 4 ] 
c=a.splice(1)
console.log(a,c)//[ 1 ] [ 5 ]
d=a.splice(0,1,20,[10,15]) 
console.log(a) //[20,[10,15]]


6. 怎样避免全局污染?箭头函数的特点是什么?

可以在一个对象区域内定义变量,这样所有定义的变量都承载在这一个大变量之下,就不存在全局变量。可以借鉴jQuery的方式,使用匿名函数,在其内部定义变量,(function(){})() 。也可以使用let,这样定义的变量仅在一个大括号内起作用。

详见此篇文章:https://www.cnblogs.com/hjvsdr/p/7485592.html

箭头函数的常用特点:function f1(a,b){  }可以被写成 (a,b)=>{},这样保证函数体内的this,同此函数外的this,保持一致。箭头函数没有原型(prototype)

7.js怎样实现一个类?

js中有对象的概念,就是一个个属性的集合。对于类,js中并没有明确的定义,可以通过原型对象的方式来实现类,以用来共享一些方法。一般方法是(1)创建构造函数,构造函数的名字即是类名,首字母大写。构造函数中的属性值针对于实例后的实例,是专属于实例的。(2)通过函数名.prototype来添加共享的方法或者重写预定义的原型对象。(3)通过new关键字就可以实例化构造函数,实例中的 __proto__指向原型并继承原型中的方法。es6通过关键字class,从形式上更加方便的实现了类,但本质上并没有改变。

详见本人另一篇博客:https://blog.csdn.net/mia1106/article/details/89260735

8.闭包是什么含义?

闭包可以读取函数内部的变量。闭包的形成:在一个函数体中,包含另外一个函数,内部函数里使用了外层函数的变量,同时外层函数把内层函数作为返回值返回。当外部执行这个返回到外部的内层函数时,会形成闭包。由于内层函数被返回到全局且引用了函数体内的变量,这样在函数体外部,就可以读到函数体内的变量了。

因此,闭包有两个作用,一是可以读取到函数内部的变量。二是可以将变量保存在内存中。

9.数组去重怎么实现?

//数组去重
var arr=[2,3,4,3,3,3,5,13,4,31,2];
//
var arrNew=[]
for(let i=0;i<arr.length;i++){
    //如果arrNew中不存在,则放置到arrNew之中
    let flag=0;
    for(let j=0;j<arrNew.length;j++){
        if(arr[i]==arrNew[j]){
            flag=1;
            break;
        }
    }
    if(!flag){
        arrNew.push(arr[i]);
    }
}
console.log(arrNew)

10.深拷贝和浅拷贝的区别,怎么实现?

深拷贝主要应用于对象和数组。因为对象和数组,如果直接拷贝,即浅拷贝,赋值过去的是地址。这样两个变量会互相影响。对于其它类型的数据,直接拷贝即可。深拷贝实现的两种方法,见下。

这篇文章,也有较详尽的叙述https://www.cnblogs.com/echolun/p/7889848.html

//深拷贝与浅拷贝
//浅拷贝举例
var obj={a:1,b:[2,3]};
var obj1=obj;
obj.a=10;
console.log(obj1,obj)//{ a: 10, b: [ 2, 3 ] } { a: 10, b: [ 2, 3 ] } 两组变量互相影响
//深拷贝
var obj2={a:1,b:{c:3,d:{f:4}},e:[11,12]};

//方法一
function deepClone(obj){
    var objCopy=Array.isArray(obj)?[]:{};
    for(let k in obj){
        if(typeof(obj[k])=='object'){
            objCopy[k]=deepClone(obj[k])
        }else{
            objCopy[k]=obj[k]
        }
    }
    return objCopy;
}
console.log(deepClone(obj2));//{ a: 1, b: { c: 3, d: { f: 4 } }, e: [ 11, 12 ] }
//方法二
function deepCopy(obj){
    return JSON.parse(JSON.stringify(obj));
}
console.log(deepCopy({a:1,b:[3,4]}))//{a:1,b:[3,4]}

11.下面代码的输出是什么?

for(let i=0;i<10;i++){

    setTimeout(
        
       ()=>{ console.log(i)},1000)
}



for(var i=0;i<5;i++){
    setTimeout(
        ()=>{console.log(i)},1000
    )
}

 

 

其它

1. Ajax 跨域有哪些方法,jsonp 的原理是什么?

1)使用jsonp。jsonp的原理是script本身就允许加载跨域的js文件。

前端所作设置:

<script>

function doSomething(data){

.....处理data

}

</script>

<script url?callback="doSomething(data)"></script>

后端也需要做处理。

只适用于get请求

2)后端做响应头设置,前端不做任何设置

后端需要在响应头增加 : 
Access-Control-Allow-Origin:http://localhost:8081 
Access-Control-Allow-Methods:GET 
两个字段都可以填写*表示所有域名和请求都可以跨域

3)jQuery有做jsonp的封装

参考:https://blog.csdn.net/yewenxiang/article/details/80115103

2.Http协议的头字段了解哪些?一个完整的http请求是什么?

头字段:Accept-Charset,希望服务器端返回的编码格式;Content-type:服务器端返回的内容的类型以及编码格式

Accept-language,希望服务器端返回的语言类型;Content-language:服务器端返回的语言类型

http请求:浏览器建立 TCP连接,浏览器向服务器发送请求命令,浏览器发送请求头,服务器端应答,服务器端发送应答头,服务器端发送内容,服务器端关闭TCP连接。(https://www.cnblogs.com/linjiqin/p/3560152.html

常见的协议头字段:https://www.cnblogs.com/le220/p/8661934.html

关于 Http的知识详解:https://www.cnblogs.com/ranyonsue/p/5984001.html

3.cookies,sessionStorage和localStorage的区别

共同点:都是在浏览器端存储数据

区别:(1)webStorage 存储数据更大,且仅在客户端存储数据。cookies每次都会随同http请求,在客户端与服务器之间传送,会占用带宽。

(2)localStorage 如果不特别删除设置,会一直保存在客户端。sessionStorage会随着浏览器关闭,而消失。

(3)sessionStorage不在不同的浏览器窗口共享。另外两者,只要是同源的,不同窗口的数据可以共享。

4. 如何解决浏览器的兼容性问题?

 

5.了解 promise吗?

 

前端框架

1. Vue的生命周期是什么?

Vue的生命周期有beforeCreated,这时创建了vue实例,但是并没有初始化$data,$el;created,此时data属性已经创建,$el并未初始化;beforeMounted,挂载dom之前,此时$el已经初始化;mounted,挂载完成,其中的值也被真正的值填充;beforeUpdated,出现更新之前;updated,出现更新之后;beforeDestroyed组件销毁之前。destroyed,组件销毁之后。

参考文章:https://segmentfault.com/a/1190000008010666

2. Vue的实现原理是什么?是否看过源码

Vue主要是基于MVVM原理。 View-model以及View之间实现双向绑定。

实现这个原理又基于Observer,Compiler,Water。

1.Observer: 能够对数据对象的所有属性进行监听,内部函数可以定义setter,getter.如果属性有变化,可拿到最新值并通知订阅者。

2.compile:对元素的每个节点的指令进行扫描和解析,根据指定模板替换数据,以及绑定相应的更新函数

3. watcher:作为observer和compile的桥梁,能够订阅并收到每个属性变化的同制,执行指定绑定的相应的回调函数,从而更新视图。

可参考别人的文章:https://segmentfault.com/a/1190000013294870

https://www.cnblogs.com/tylerdonet/p/9893065.html

 

 

前端工程化

1. 为什么要前端工程化?

(1)是其模块化/组件化

从软件工程的角度来考虑,我们希望我们的项目是“高内聚,低耦合”,原有的前端模式,代码会分别写在html,css,js文件中,所有的内容都基本上分布在这三个地方,这样每份文件都担负巨大的代码,不便于书写,不便于维护,不便于管理。工程化之后,将项目模块化/组件化,可以分工协作一个项目,也便于管理和维护。

(2)重视代码规范

工程化中,前端代码的规范性也会被提到。这也有利于团队的协作和维护。

(3)其它等

前端工程化还包含分支管理,自动化测试,构建和部署。

前端的工程化,是一个需要长期累积的实践经验,首先,可以打开工程化的项目,看其主要的结构模式,其次,我们很多时候练习的是web应用开发,可以在开发的过程,扩展理解的层面,从整个开发到部署的整个工程去学习与认识。

以下这篇文章是对于前端工程化的理解:

https://www.cnblogs.com/fsyz/p/8274727.html

https://www.jianshu.com/p/171996f5b12c

 

 

欢迎对问题进行讨论,如果对您有用,别忘记点赞喔。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章