前端面试题全面总结!

HTML

1、行内元素有哪些?块级元素有哪些?空元素有哪些?

行内元素:span、img、input、em、i、label...

块级元素:p、h1、div、ol、ul、table、form...

行内块元素:img、input(可以设置宽高)

空元素:br、hr、meta、img、link

涉及元素之间的转换:display属性

2、link和@import的区别

link是html的标签,@import是css的样式规则。

link能加载样式文件、图片等资源,@import只能加载引用样式

link与引入的css被同时加载*(并行),@import页面后加载(串行)。

后者兼容性差。

3、title与h1,strong与b的区别,i与em的区别

title是网页标题,h1是内容。网站seo(网站搜索优化)层面上,title级别更高

加粗:语义化区别,b只是加粗,strong且有强调(阅读器)作用。

倾斜:i多用在做图标,em也有强调作用。

4、img的title和alt属性的区别

title:鼠标移入图片时显示。

alt:图片不加载时显示。

5、jpg、png、gif的区别

jpg:适合大图片,同样的图片相对用png体积更小。(失帧)

png:适合小图标,同样的图片体积更大。(失帧小)

gif:动态图

6、DOCTYPE作用

DOCTYPE是一种文档类型声明,它的目的是告诉浏览器(解析器)应该以什么样(html或xhtml)的文档类型定义来解析文档。它必须声明在HTML⽂档的第⼀⾏。

浏览器渲染页面的两种模式:标准模式和怪异模式。

7、meta标签的理解

meta标签由name和content属性组成,用来描述网页文档的属性。

charset,用来描述HTML文档的编码类型。

name:keywords、description、viewpoint

8、input和texarea的区别

input是单行文本框,通过size属性限制字符长度,可以设置宽高,但始终是一行。

texarea是多行文本输入框,使用cols和rows规定尺寸。

9、src和href的区别

src:source的缩写,直接加载出引入的资源。img、style、video、audio。

        当浏览器解析到该元素时,会暂停其他资源的下载和处理,进行资源请求。

href:建立与外部资源的连接通道。a、link。

10、语义化标签

语义化就是用合适的标签用在最恰当的内容上。

1、没有样式情况下,语义化标签呈现清晰结构,方便机器和工作人员阅读代码。

2、有利于seo,提高关键字权重,使爬虫抓取更多有效信息,提高搜索引擎名次。

3、方便盲人阅读器等设备渲染页面。

11、HTML5新增标签

header:网页头部,footer:网页底部,nav:网页导航,section:区段

article:独立内容,aside:侧边栏。

前端面试题全面总结!_第1张图片

12、HTML5新特性——

1、各种新增表单类型:email、number、date、week、search、range、color

        datalist、option:选择表单

2、音视频——video、audio

controls="controls"用户控制音乐, loop="loop"循环播放, preload="auto"自动播放。

3、画布——Canvas+SVG

Canvas:画布,位置发生改变会重新绘制。getElementById——getContext

SVG:可缩放矢量图,基于XML。

4、本地存储——localstorage、sessionstorage

5、可编辑属性:contenteditable

广泛应用在用在网页编辑器、编辑状态。在标签内部加入contenteditable=“true”

5、Web worker

在执行脚本时,页面的状态是不可相应的,直到脚本执行完成后,页面才变成可相应。

6、drag拖放事件

7、地理位置API

13、svg是什么?怎么使用? 

 svg是可伸缩矢量图形,图形在放大或者改变尺寸的情况下图形质量不会损失。

画图:rect(矩形),polygon(多边形)、circle(圆形,cx和cy定圆心)、ellipse(椭圆)

结合css的animation产生动画效果。

14、canvas是什么,怎么使用?

html添加Canvas标签,设置ID、宽度和高度

js通过getElementById获得canvas标签,使用getContext确定图片类型。

//绘制三角
function draw(){
    var canvas = document.getElementById('tutorial');
    if (!canvas.getContext) return;
    var ctx = canvas.getContext("2d");
    ctx.beginPath();
    ctx.moveTo(50, 50);
    ctx.lineTo(200, 50);
    ctx.lineTo(200, 200);
  	ctx.closePath(); //虽然我们只绘制了两条线段,但是closePath会closePath,仍然是一个3角形
    ctx.stroke(); //描边。stroke不会自动closePath()
}
draw();

css

1、css盒子模型

盒子模型:标准盒子模型、IE盒子模型

标准:margin+border+padding+content。

IE:margin+content(border、padding、content)

盒子模型转换:box-sizing:content-box(标准),border-box(IE盒子)

1、盒子塌陷与解决方案

盒子塌陷:内部盒子跑到父盒子的外部

原因:内部盒子脱离文档流

解决:清楚内部盒子浮动、父亲盒子高度写死。

2、line-height和height的区别

line-height:每行文字的高度,如果文字换行则整个盒子高度增大(行数*每行高)

height:盒子的纯高度。

line-height:height值,文字垂直居中。 

3、css选择器有哪些?哪些属性可以继承

通配符选择器(*),id选择器(#),类选择器(.),标签选择器。

相邻选择器(+匹配一个,~匹配多个),后代选择器(空格),并集选择器(,),子元素选择器(>),

属性选择器(input[disabled])


可继承样式:字体font系列,文本line-height、color、text-align,list-style。

不可继承:border、margin、width、height

3、伪类选择器和伪元素选择器

伪类

        状态伪类:lvha
        否定选择器:div:not(span)选中出来除了括号里的其他元素

        其他:div:first-child    div:last-child    div:nth-child()    div:nth-of-type(锁定类型)

伪元素

        div::after

        div::before

        div::selection  设置选中文本的样式

4、css优先级算法

!important>内联样式>id选择器>类选择器(属性、伪类)>标签选择器(伪元素选择器)>通配符

权重:max       1000        100         10               1                                          0          

5、画三角形(用border)

width和height设置为0

border一个边设置为:100px solid 颜色

另外三个边框设置为:100px solid transparent(透明)。

6、水平垂直居中

display:inline-block;margin:0 auto(水平居中)

1、用flex布局给父元素设置:

        display:flex;

        justify-content:center;

        align-items:center

2、grid布局:

        父:display:grid

        子:align-self:center

                justify-self:center

3、用定位动画给自己设置

        position:absolute;

        top:50%;

        left:50%;

        transform:translate(-50%,-50%)

4、table-cell

        display: table-cell;

        text-align: center;

        vertical-align: middle;

7、BFC

BFC:块级格式化上下文,就是将这容器变成完全独立的个体,不会影响到外面的元素。

可以触发bfc的条件有:

        float不为none,

        overflow不为visible,

        display:inline-block,table-cell

        position为absolute、fixed。

常用:overflow:hidden

 8、清除浮动影响的方式

1、触发BFC,例如用overflow:hidden

2、ul:after{

                dispaly:block;

                content:"";

                clear:both

        }

9、position定位

static:默认值,不定位。

relative:相对定位,相对于原来自己进行定位。(对其他元素不太影响,不脱离文档流)

absolute:绝对定位,相对于已定位的父元素进行定位(没有的话就是浏览器大框)。

fixed:固定定位,相对于浏览器大框进行定位。

sticky:粘性定位,在屏幕范围(viewport)时该元素的位置并不受到定位影响(设置是top、left等属性无效),当该元素的位置将要移出偏移范围时,定位又会变成fixed,根据设置的left、top等属性成固定位置的效果。

边偏移属性:top:100px(向下移动100px),right,left,bottom。

(relative如果有上下左右,只要上和左的,absolute则全有)

10、双飞翼布局(左右200宽,中间自适应,先加载中间)

1、中左右顺序设置模块,给左设置margin-left:-100%,给右设置margin-left:-200px

2、子项目设置flex-shrink属性,0为固定,1为可伸缩,自适应的设置flex:1

11、什么是 css reset

reset.css,是css一个css文件,重置css样式。

例如还有normalize.css,同样也是。

12、css sprite是什么?优缺点?(雪碧图、精灵图)

sprite是把多个小图标合并成一个大图片。

使用:ps或者第三方工具CSS sprites generator

优点:减少http请求次数,提升了性能。

缺点,维护性比较差(如果内容更改)

13、进程和线程

进程:一个进程就是一个程序运行,启动程序,系统会为它创建一个内存,程序的一个运行任务会在一个线程,任务所在的大运行环境叫做进程。

线程:程序执行的最小单位。

        线程依附于进程

        进程的任意一个线程执行出错,都会导致整个进程的崩溃,其他线程不能运行。

        一个大程序有多个进程,其中一个崩溃不影响其他的

浏览器进程:浏览器每一个页签都是一个独立的进程,进程内的线程只会影响自己。

渲染进程:将html、css、js渲染成网页,浏览器回为每一个Tab标签创建要给渲染进程。(包括GUI渲染线程、js线程,定时器线程)

13、浏览器渲染线程

根据url,通过网络请求,得到服务器传来的代码,返回文本文件,浏览器将文件转成html。

根据html解析器对html文件解析根据节点生成DOM树,

根据CSS解析器对css文件解析生成cssom。

将DOM和CSSOM整合形成render tree(计算布局数据)

根据render tree开始绘画渲染(重绘)、布局展示(回流)

        (布局进行分层,每个图层生成绘制列表,图层分成块,光栅化图块转换成位图)

        分层为了提高渲染性能,例如动画渲染不影响其他图层。

        光栅化目的是将不需要的图块不做渲染。

        提升图层:will-change:transform

遇到link、script时,去请求响应文件。

js文件最好写在最后,不然会阻塞渲染,

14、display:none和visibility:hidden的区别。

display:none,隐藏后不占用原位置。产生重绘与回流。

visibility:hidden,隐藏后占用原位置。产生重绘,不会回流。

原理:浏览器渲染过程↑ +重绘与回流(重排)↓

14、隐藏某个内容的方法

1、opacity:0;

2、visibility:hidden;

3、display:none

15、重绘与回流(重排)

回流(重排):当render tree的元素改变了自身的宽高、布局、显示或隐藏,或者文字结构改变,产生回流。

重绘:只是改变各元素的外观(颜色等),产生重绘

回流必有重绘。

优化,避免回流:

        不要使用 js 代码对dom 元素设置多条样式,选择用一个 className 代替之。

        定位使用absolute或者fixed脱离文档流。

        transform 代替 top,left ,margin-top, margin-left... 这些位移属性。

16、透明:opacity与rgba的区别

都是实现透明的效果。

opacity:取值0-1,0表示完全透明,1表示完全不透明。会继承给子元素

rgba:(red,green,blue,透明度取值0-1),不会继承。

17、position、display、overflow和float的优先级

position:absolute/fixed优先级最高,有他们在时,float不起作用,display值需要调整。float 或者absolute定位的元素,只能是块元素或表格。

18、解决上下margin重合的问题

在其中一个盒子外包一个div,并对其触发BFC

19、伪元素,::before 和 :after中双冒号和单冒号有什么区别?解释一下这2个伪元素的作用

css3规范使用双冒号,单冒号是hover等伪类。

20、css实现动画

transition常见属性

        transition-property:设置的属性名如height

        transition-duration:过渡时间

        transition-delay:延迟时间

        transition-time-function:速度变化,默认ease(缓冲)

        (四个可以合并使用。)

        缺点:一次性,不能重复发生。需要事件出发,不能在网页加载时自动发送。只能定义在一个对象上。只有开始和结束状态。

animation可以实现上面缺点

        除了上方四个属性,还有:

                animation-name:给动画起名字

                animation-iteration-count:循环次数

        结合@keyframes name{ }使用。

21、实现loading图(加载图),四分之三圆并旋转。

1、设置border-radius:50%产生一个圆,再设置其中一条border为透明色。

2、动画:为设置的四分之三圆设置rotate旋转动画,用infinite设置无限循环

22、Flex布局

父级:

        flex-direction:主轴方向

        justify-content:主轴上对齐方式(水平)

        align-items:侧轴上对齐方式

        flex-wrap:是否换行

子级:

        align-self:子元素在侧轴对齐方式

        order:排序,越小越靠前

        flex:flex-grow(占比几份)、flex-shrink(0固定、1自适应)、flex-basis(auto)

23、px、em、rem、vh、vw区别

px:像素单位

em:font-size的大小,默认1em=16px,会继承。em值对font-size变化而变化。决定部分

rem:根据html根的font-size大小决定。1rem=16px。rem值固定,可以调整整体文字。决定所有

vw、vh:宽高的1%

24、让超出宽度的文字显示省略号

white-space:nowrap。设置为不换行

overflow:超出隐藏

text-overflow:显示...

25、瀑布流布局

box:flex+column+wrap+height:100vh

item:calc(100%/n)

JS

1、延迟加载js有哪些方式

延迟加载:async、defer(无论js的位置在哪里)

 两者区别:

        async:异步加载,此时js的下载和html的解析一起走,但不确定js的执行顺序。

        defer(最好): 异步加载并推迟执行,再执行js文件代码,顺次执行js脚本。

       

2、js数据类型有哪些?

基本数据类型:string、number、Boolean、null、undefined、symbol、bigint

引用数据类型:object(array、function)

数据类型转换:

        toString()转化成字符串。

        Number()转换成数字。有一个字符不是数值就返回NaN

        parseInt()转化成数字。第一个字符不是数字就返回NaN

        Boolean()转化成布尔值

2、symbol和bigint

symbol:

可以给对象设置一个私密属性,别人访问不到。属性值不会被改写或者覆盖。
let id1 = Symbol('id');symbol同一个变量生成的值也不相等。

for in和object.keys都访问不到,可以用getOwnPropertySymbols访问


bigint:

大整数、提供一个表示大于2^53-1的整数。

number只能支持-2^53-1到2^53-1的数,超过就会失去精度,被四舍五入。

var bigInt = BigInt("9007199254740999")

2、如何判断一个数是整数

1、toString+正则

2、parseInt结果与原值比较

3、Number.isInteger()

4、对1取余是否为0

2、数据类型判断:数据类型的判断_在寒夜等候光明的博客-CSDN博客_判断数据类型的方法

typeof:判断类型number, string, boolean, function, undefined,object(对象或者null)

instanceof:一般用来判断引用数据类型的判断,如:Object,Function,Array,Date,RegExp等。原理:右边变量的 prototype 在左边变量的原型链上。

constructor:当一个函数被定义时,JS会为函数添加prototype原型,然后再在prototype上添加一个constructor属性,并让其指向F的引用。

object.prototype.tostring.call()精准判断

3、null和undefined的区别

作者先设计的null,后设计的undefined。但是null==undefined,null===null,undefined===undefined

null是“空”,undefined是“未赋值”。

typeof(null)结果是object,number(null)为0。

typeof(undefined)为undefined ,number(undefined)为NaN

false == undefined是false,因为会被转化为数字:null 被转化为 0,undefined 被转化为 NaN。

4、==和===的区别

==:比较的是值

        其中原理是原型的valueof隐式转换,在内部自动调用,不会显式改变。

===:比较的是值和数据类型。

4、隐式转换和显式转换

隐式转换:自动转换数据类型(转换了但是不显示),==判断、运算

显示转换:强制转换。number()、boolean()、parseInt()

5、js的执行机制。

JavaScript是单线程的语言,前一个任务执行完执行下一个任务。

同步任务:主线程上排队执行的任务。

异步任务:不进入主线程,进入任务队列。主线程任务完成,执行异步任务。

js代码执行顺序是:同步任务=》进入任务队列的异步任务进行事件循环(微任务全部完成=》宏任务)

同步:clg,for循环,promise紧跟着的代码。

微任务:promise.then,async的await。

宏任务:setTimeout,ajax请求

6、关于作用域、变量提升:JavaScript函数作用域 - Web前端工程师面试题讲解_哔哩哔哩_bilibili

只有函数才会有作用域,for循环可没有。

作用域分为全局作用域、局部作用域、块级作用域。

函数内部可以访问外部的变量,但是外部不能访问内部的变量。

优先查找内部的变量,内部没有,再去外部找。(作用域链)

js的var有声明提升,函数也会声明提升,函数的提升高于变量的提升。

7、js对象考题  

1、对象是new出来的,所以相同对象不相等。【1,2,3】==【1,2,3】结果是false。

2、对象是引用数据类型,数据在堆内存的一个共同的内存地址中。

3、对象的key值都是字符串类型。

4、对象查找属性/方法的顺序:

        对象自身——构造函数自身——对象原型——构造函数原型——object

7、object的api有哪些

Object.defineproperty(obj,prop,属性描述符)

        直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。

        前端面试题全面总结!_第2张图片

Object.keys(obj)

        返回给定对象的自身可枚举属性的数组

Object.assign(obj1,obj2)

        合并对象

7、面向对象的三个特征

封装:可以隐藏实现细节,使得代码模块化

继承:可以扩展已存在的代码模块,为了代码重用

多态:相同的事物,调用其相同的方法,参数也相同时,但表现的行为却不同。

7、模块化的CommonJs和es6的区别

前者是module.exports+require方式的模块化,输出的是一个模块的拷贝,运行时加载

后者是import from方式的模块化,输出的是模块的引用,编译时加载

7、es6新特性

let、const关键字

箭头函数

模板字符串

扩展运算符

解构赋值

数组方法

8、如何判断变量是不是数组?有几种办法? 

方法一:Array.isAarray(arr)

方法二:arr instanceof Array

instancof实现原理:prototype 在左边变量的原型链上

方法三:原型:Array.prototype.isPrototypeOf(obj).

方法四:构造函数:arr.constructor.toString().indexOf("Array")>-1

9、slice和splice是干嘛的,splice是否会改变原数组

slice是切片,截取。

        arr.slice(a,b):a参数是开始索引,b参数是结束索引。没有b参数就一直到最后。

                返回的是截取出来的数组。

splice:数组插值

        arr.splcie(a,b,c):a参数是开始索引,b参数是选择个数,,c参数是要替换的内容。

                返回的是删除掉的元素。

两者都会改变原数组。 

10、数组去重

1、set+扩展运算符(使用于数组对象字符串)

2、循环+indexof(新数组中-1时推到新数组)

3、filter+indexof当前元素等于当前索引

11、new操作符具体做了什么?

1、创建了一个空的对象

2、使空对象的原型指向构造函数的原型。

3、改变this指向,指向该对象实例

4、对构造函数的return做出判断。若return一个基本类型则无影响,return对象会改变为这个对象。

12、闭包

js有全局变量和局部变量,函数内部可以访问函数外部的变量,但是函数外部无法读取函数内部的局部变量。
但是闭包可以做到,闭包是定义在一个函数内部的子函数,有权访问这个函数作用域中的变量。

我的理解闭包是函数内部和函数外部连接起来的桥梁。

优点:函数外访问函数内的值,可以封装对象的私有属性和私有方法。避免变量被垃圾回收。

缺点:变量会驻留在内存中,造成内存损耗。(解决:数据设置为null)

原理:基本数据类型在栈内存,用完就销毁,引用数据类型在堆内存,有引用地址。

12、内存损耗的几种情况

闭包

未被清空的定时器

未被销毁的事件监听

DOM引流

13、原型和原型链

前端面试题全面总结!_第3张图片

所有的函数都有prototype属性(原型),数组和对象没有,prototype上可以设置属性和方法来继承给实例。实例对象都有__proto__属性,对象的_proto_指向构造函数的prototype。逐层深入直到Object对象的原型,这样就形成了原型链。

对象查找属性/方法的顺序:

        对象自身——构造函数自身——对象原型——构造函数原型——object

13、call、apply和bind

三个方法都是用来改变this指向,

call、apply可以立即执行,bind不会立即执行,可以赋值给一个对象。

call和bind的第二个参数和后面参数依次写,apply的参数是数组。

14、浅拷贝和深拷贝

都是copy复制的意思

浅拷贝:只复制引用地址,不复制真正的值。要改变一起改变。

        场景1:var arr=[1,2,3]       var arr2=arr

        场景2:arr.slice()和arr.splice()

        场景3:引入lodash库,使用clone方法

        场景4:Array.from()类数组转为真数组。

深拷贝:复制真正的值。

        场景1:obj2=Json.parse(Json.stringify(obj1))

        场景2:arr2=[...arr1]和Object.assign(对象来说,一层是深拷贝,多层是浅拷贝)

        场景3:lodash库的cloneDeep()方法

15、localStorage、sessionStorage、cookie的区别

都是在客户端存储数据

localStorage:当前浏览器关闭,永久保存,设置的数据(setitem)也会存在。存储不能超过5M

sessionStorage:当前浏览器关闭,设置的数据也会消失。存储不能超过5M

cookie:可以设置过期时间,过期前一直保存。存储不能超过4k

16、怎么让Chrome支持小于12px的文字?

Chrome的默认字体是16px,

可以通过将span元素设置属性

(display行内块并进行动画缩放。)

17、移动端:如何禁止ios&Android长按时触发系统菜单、长按时下载图片、用户选中文字

禁止移动端长按时触发系统菜单:

        全局设置:

禁止移动端长按时下载图片:

        全局设置:

 禁止移动端用户选中文字:

        全局设置:

18、自适应(不同手机型号自适应内容)

引用移动端meta

引入淘宝无限适配的js文件

布局单位使用rem

19、响应式、媒体查询

响应式就是一个URL可以适配移动端和pc端中调整。

语法结构:前端面试题全面总结!_第4张图片

关键词:only:只支持媒体查询的浏览器

              screen:设备

              max-width丨max-height   min-width丨min-height

响应式图片:对图片尺寸进行优化。使用source标签(可替换他图片)

        前端面试题全面总结!_第5张图片

20、布局方案

使用响应式布局的情况:

        数据不是很多,用户量不是很大的展示类页面

        例如:公司官网、专题页面

        大网站若采用大量响应式,会造成网页加载缓慢。

pc+移动双端网站使用的布局:

        pc是一个URL,会加入一些响应式。

        移动端是另一个URL,会使用自适应的布局方式。

前端面试题全面总结!_第6张图片

21、var、let、const的区别

三者都是用来声明变量。

区别1:var有变量提升,let和const没有。

区别2:var可以声明覆盖同一变量,let和const会报错。

区别3:var和let声明的变量可以改变,const声明的常量不可修改。

区别4:let和const会产生块级作用域,var没有。

21、暂时性死区

let和const会有他们所在的作用域,进入作用域时,声明的变量已经存在了,但是不可获取,只有等到声明变量的那一行时,才可以获取和使用变量。

var声明提升,所有没有暂时性死区,未达到时为undefined。

22、箭头函数和普通函数的区别

1、this指向: 

        箭头函数this指向=该箭头函数外层第一个普通函数的this,且this不可修改

        普通函数或方法:谁调用this指向谁

        匿名函数的this:匿名函数具有全局性,指向window

2、箭头函数不能new(不能当做构造函数)

3、箭头函数没有prototype。

4、箭头函数没有arguments。

22、关于arguments的相关问题

函数传参时,js会把所传的参数全部存到一个名为arguments的类数组对象中。

有了这个对象我们以后写函数的时候,就不用给所有的形参指定参数名,直接使用arguments对象来获取实参。

23、回调函数和回调地狱

回调函数:作为实参进入另一个函数,并在此函数中被调用。解决异步问题。

回调地狱:多个回调函数嵌套的话,使代码看起来很混乱,不利于维护。

24、set、map的区别(new map,new set)还有weekset和weekmap呢?

set:是一组不重复数据的集合,可以用于数组去重。

        两个空对象不重复,是两个值,因为内存地址不同。

        方法:可以遍历,size长度,add添加,has判断是否有

map:(类似python的字典)是存放键值对的集合,键和值都可以是任意数据类型

        通过map实例.set()的方法给map添加键值对。

        可以遍历,方法get、has等。

weekset:对象的集合,成员都是对象。

                不能遍历,方法有 add、delete、has

weekmap:键名只能为对象,不能遍历,对象只作为键、不被引用的话自动清除,不计入垃圾回收机制,上同。方法有 get、set、has、delete

25、什么是函数的柯里化?怎么解决?

柯里化:把一个多参数的函数转化成单参数函数的方法,多参数各分一个函数。

                前端面试题全面总结!_第7张图片 

核心:函数里面返回函数

作用:参数依次延迟执行。

实例:js中经常使用的bind,实现的机制就是Currying 

26、数组和伪数组(类数组)的区别

数组是特殊对象,有各种从原型中继承的数组方法。

类数组是简单对象,有length属性,但不能调用数组方法。(arguments对象、getelementbyid等获得的),对象也算是伪数组。

类数组转换成真数组:

1、Array.from()

2、[...伪数组]

3、Array.prototype.forEach()。属性遍历并组成新的数组

26、各种数组方法:Javascript常用的数组方法_Humor_Mr的博客-CSDN博客_js数组常用方法

27、了解es6的Proxy吗?

proxy,代理。产生对象前,对其拦截包装操作

前端面试题全面总结!_第8张图片

28、js继承

1、原型继承:父类的实例作为子类的原型。

                        缺点:引用类型改变后会被共享。

                        前端面试题全面总结!_第9张图片 

2、构造函数继承,var a=new A()

                        缺点:子类不能访问父类原型上的属性

3、上面两个组合继承。

                        缺点:调用两份一样的父类的属性方法。影响性能。

4、寄生组合继承:前端面试题全面总结!_第10张图片

5、es6的Class类继承:extend+super 

29、图片懒加载:js实现图片懒加载原理_tomorrownan的博客-CSDN博客_图片懒加载

图片按需加载,如果页面没到该图片,则不加载

实现办法:

        加载完页面,使用data-src存储每个img标签的src值。

        获取图片上边界getBoundingClientRect().top和浏览器可视高度clientheight,并比较

        通过把data-src的值赋值给img的src属性。

        然后img生效。

前端面试题全面总结!_第11张图片

最简单方法:设置属性loading="lazy" 

30、DOM原生操作

创建新节点:createElement:创建一个具体元素。

添加:appendChild()

移除:removeChild()

替换:repalceChild()

插入:insertBefore()

克隆:cloneNode()

设置和获取属性:setAttribute("属性名","属性值"),getAttribute("属性名")

30、BOM是什么?

浏览器对象模型。也就是浏览器操作

history:back()、forward()、go(1、-1)

navigator :

location:属性:href地址、host域名、port端口、pathname路径、search参数

alert、confirm、open

30、事件冒泡和事件捕获

事件冒泡:事件向上传导。子事件的点击事件被触发,祖先元素的点击事件依次会被触发。

事件捕获:与冒泡相反,从父到子。

addeventlistener,第三个参数默认false冒泡

event.stopPropagation()组织冒泡

event.preventDefault()阻止默认事件

@click.stop=

30、js内置对象

Set、Map、Math、RegExp、Number、Array、Boolean、Object。

31、对于Json的了解

Json是一种数据交换格式,采用键值对,键值都是字符串。

32、js的垃圾回收机制(主要是堆内存)

垃圾回收:找到不再使用的变量,释放掉其占用的内存。 

标记清除:函数中的变量被标记,当函数执行完,将变量的内存释放,其他的先复制进空闲区域。

引用计数:内存变量被引用就+1,变量用完-1,直到0释放。
var a=1;

a=100,1的空间不用了,垃圾回收。

前端面试题全面总结!_第12张图片

32、避免内存泄露的方式

导致内存泄露有:定时器未清除、闭包、脱离DOM引用

尽可能少地创建全局变量(因为一直在,不会被垃圾回收)

手动清除定时器

少用闭包

清除DOM引用

使用弱引用weakMap和weakSet(垃圾回收时不会将创建的键值考虑进去)

33、严格模式

使用:use strict

概念:消除js语法中的不合理、不严谨、不安全的地方,减少怪异行为,保证代码正常运行

限制:全局下的this指向undefined。

           构造函数必须加new。

           函数不能有重名的参数。

34、mvc和mvvm的理解?

MVC:模型-视图-控制器        

        view传送指令到controller

        controller完成逻辑后,通知model改变状态

        model发送新数据给view,完成视图更新。

MVVM:model-view-viewmodel        

        model:数据访问、数据存储       

        view:ui界面

        viewmodel:view和model的信息转换

35、异步编程的实现方式

1、回调函数

2、事件监听

3、promise

4、generator

5、asyac、await

35、谈谈对Promise的理解

promise是异步编程的一种解决方案,可以解决回调地狱。

有resolve、reject两个参数,分别对应res、err两种参数。

继续用then链式调用,异常用catch,还有finally。

promise.all():等待机制,所有成功再执行,promise是数组,返回结果也是数组。

                        传参数组为空,立即执行resolve

promise.race():赛跑机制,有一个操作完成就可以执行。

                        传参数组为空,不会执行。

前端面试题全面总结!_第13张图片

36、什么是async和await?

async将函数标记为异步函数,返回的是promise对象

await承接一个promise实例,直接得到promise.then成功的结果,await遇到具体值,就是promise.resolve(这个值)

第一个await之前的代码会同步执行。await之后的代码会异步执行(后执行)。

37、onclick和addEventListener的区别

onclick可以写在标签中,addEventListener只能写在js代码中。

onclick只能绑定点击事件,addEventListener可以绑定各种事件。

onclick绑定多个事件会覆盖,addEventListener不会。

addEventListener第三个参数false是冒泡事件,true是捕获事件。

38、event事件对象

事件对象:当事件对应的函数触发时,浏览器都会将事件的相关信息传递给响应函数

事件对象包括的信息:鼠标坐标(e.clientX、e.clientY)、键盘键位、滚轮方向……

e.target:返回触发事件的对象

e.preventDefault:阻止默认行为

e.stopPropagation:阻止冒泡

39、js实现页面跳转

window.location.href=" "

window.open()

history.go(-1)

window.navigate()

40、Object.assign(a,b)?

合并:实现对象的合并

覆盖:如果已有属性重名,b覆盖a。

复制:复制的是属性值,即引用地址,(浅拷贝)。

41、for of和for in

for of适合遍历数组,for in适合遍历对象。

for of遍历对象会报错。

for in遍历的是数组的索引,对象的属性,以及原型链上的属性。

42、js小知识点

  • !!双重取反,不为false布尔值时为true。
  • ??是合并运算符,当左边不为null和undefined时,返回左边,否则返回右边
  • 判断对象是否有某个属性,x in obj返回布尔值,hasownproperty()
  • 高阶函数:将函数作为输入或返回值的函数。
  • event.target是发生事件的元素或触发事件的元素。
  • eval()函数可以接受一个字符串str作为参数,并把此str当做一段javascript代码去执行
  • void运算会忽略掉求值的结果,直接返回 undefined、
  • Object.entries() 方法返回一个给定对象自身可枚举属性的键值对数组。
  • 数组方法arr.at(index),返回index的元素。
  • 数组方法arr.includes(元素),判断数组是否有某个元素。
  • 数组扁平化:flat(2或infinity):递归深度遍历数组,并合并成新数组(多层变一层)。(会移除空的项)
  • 判断字符串是否以某个字符串开头或者结尾:startwith、endwith

43、js手写前端面试手撕题整理(自用)_笔经面经_牛客网

手写一个promise的sleep

前端面试题全面总结!_第14张图片

手写并封装一个ajax请求

前端面试题全面总结!_第15张图片

手写instanceof

前端面试题全面总结!_第16张图片

Vue

1、vue生命周期有哪些?

1、系统自带的八个有:

        beforecreate、created、beforemount、mounted、beforeupdate、updated、beforedestroy、destroyed。

2、进入页面,执行的生命周期有:

        beforecreate、created、beforemount、mounted。

3、created产生数据(vue有@data),mounted开始挂载DOM(有@el)

4、当有keep-alive时,多两个生命周期:deactivated、activated

当有keep-alive时,第一次进入组件执行的生命周期:

        beforecreate、created、beforemount、mounted、activated

当有keep-alive时,不是第一次进入组件执行的生命周期:

        只执行activated

deactivated 在keep-alive组件激活之后当隐藏缓存组件时触发

keep-alive组件的使用

keep-alive 可以使被包含的组件保留状态,缓存组件,避免被销毁。

vue组件的data为什么必须是一个函数?

vue对象中,data写成一个函数实际就是形成一个闭包。

数据return出来,相当于每个组件实例都有自己的私有属性。

如果不写成对象,一个data的某个值改变,其他组件的data也会受影响。

2、谈谈你对keep-alive的了解

keep-alive是系统自带的一个组件,切换组件时,把切换出去的组件保留在内存中。

防止重复渲染DOM,提升性能。

(组件被包裹在keep-alive标签中。)

3、v-if和v-show的区别

v-if 为false时,此DOM节点直接消失。

v-show为false是,DOM依然存在,样式改为display:none。

v-if更高的消耗。v-show适合频繁切换。

4、nextTick干嘛用的?

在data()中的数据修改后,页面中无法获取data修改后的数据。

使用$nextTick时,当data中的数据修改后,可以获得实时的渲染页面。

(nextTick是页面渲染后执行的函数)

 (后面用箭头函数,this指向vue)


使用场景:created想要获取dom、更新列表后的高度。

5、props和data的优先级谁高?

props>data

6、computed、watch有什么区别

watch:监听属性,监听一个已经存在的属性,值改变时,会调用对应的方法。无缓存

computed:计算属性,根据已有的属性改变时,计算出一个新的属性。有缓存。

7、事件修饰符和按键修饰符有哪些

事件修饰符

        @click.prevent=“事件名” ,阻止默认行为

        @click.stop=“事件名” ,阻止冒泡

        once:只触发一次

按键修饰符

        @keyup.enter="事件名",enter键触发事件

        @keyup.13="事件名",空格键触发事件

v-loader是什么,它的用途?

webpack的loader

vue文件的一个加载器,将template、js、style转换成js模块。

用途:js可以写es6、style样式

key的作用

作为每一个dom元素的唯一标识,来区别不同dom,同时通过diff算法更新dom时更加高效。

如果以index为key值,逆序删除时会有bug。可以用唯一性id作为key比如手机号。

diff算法

diff 算法的目的是根据 key 复用 dom 节点,通过移动节点而不是创建新节点来减少 dom 操作。
对于每个新的 vnode,在旧的 vnode 中根据 key 查找一下,如果没查找到,那就新增 dom 节点,如果查找到了,那就可以复用。
复用的话要不要移动要判断下下标,如果下标在 lastIndex 之后,就不需要移动,因为本来就在后面,反之就需要移动。
最后,把旧的 vnode 中在新 vnode 中没有的节点从 dom 树中删除。

vue的双向数据绑定如何实现的?试题-Vue实现数据双向绑定的原理是什么? - 校招VIP

通过数据劫持结合发布订阅者模式的方式实现的。通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应监听回调。

spa(单页面应用)和mpa(多页面应用)的区别及缺点

spa指只有一个主页面的应用,浏览器一开始就加载所有的js、html、css,所有的页面内容都在这个主页面中,写的时候还是分开写。单页面的页面跳转只刷新局部资源。

mpaL一个应用的资源分布在不同页面,页面跳转就整页刷新。

spa优缺点:

        优点:不用重新加载用户体验好。不用整个刷新服务器压力小。

        缺点:前进后退导航不可用。第一次加载资源过多

vue中事件绑定加括号和不加括号的区别

@click=“fun”
        不带括号、不写实参的fun默认传event (事件对象)

@click=“fun(value)”
        只要加括号,无论是否传值,都属于传实参给函数,event (事件对象)就接收不到。

@click=“fun($event, value)”

        如果需要实参、又需要event

改变深层数组

vue.set(对象名,属性,属性值)、vue.set(数组名、索引、值)

也可以使用数组方法push等

v-model实现原理

v-model双向绑定实际上做了两步动作:

1、绑定数据value
2、触发输入事件input;也就是说,v-model等同于: