web前端杂文让前端飞《烂俗前端》

【番外01】吐血整理五万字100道高频基础面试题 无名面试集《烂

2021-10-28  本文已影响0人  岛民小强

《烂俗前端》是一部以前端为题材的小说,涉及讨论职业、社会、技术、情感等话题,正在更新中。


之前吴明在对赵铁柱考验之前,扔了一份面试题集合让赵铁柱背,说:“你现在这个阶段,做到理解这些题还比较难,所以想过一些面试,就一个字,'背'!当然,死记硬背是在你尝试去理解未果的前提下。”,“另外,在这之前快速看完HTML/CSS/JS的基础内容, 比如两天看一遍。不然看面试题就是一脸懵逼。”

有些同学总觉得光背这些不去理解的话没什么鸟用,能理解当然好,不能理解,背会了对面试官来说,那也是属于你的知识,学习态度也算ok。

铁柱硬着头皮背了下来。下面是面试题正文。

作者:吴明

声明:本面试题非完全原创,作者负责筛选整理、编辑、补全解答、撰写。

主要读者人群:入门新人、社招面试者、初级前端。


01、什么是HTML语义化?

HTML语义化就是让页面内容结构化,它有如下优点:

1、易于用户阅读,样式丢失的时候能让页面呈现清晰的结构。

2、有利于SEO,搜索引擎根据标签来确定上下文和各个关键字的权重。

3、方便其他设备解析,如盲人阅读器根据语义> 渲染网页

4、有利于开发和维护,语义化更具可读性,代码更好维护,与CSS3关系更和谐


02、行内元素和块级元素?img算什么?行内元素怎么转化为块级元素??

行内元素:和有他元素都在一行上,高度、行高及外边距和内边距都不可改变,文字图片的宽度不可改变,只能容纳文本或者其他行内元素;其中img是行元素。

块级元素:总是在新行上开始,高度、行高及外边距和内边距都可控制,可以容纳内敛元素和其他元素。

行元素转换为块级元素方式:display:block;


03、请说出一些HTML5新增标签

能记多少记得少,太少用的我就不列出来了

章节:

文字形式:

嵌入内容:

表单:

交互元素:


04、src和href的区别


05、前端页面有哪三层构成,分别是什么?作用是什么?

分成:结构层、表示层、行为层。


06、请写出至少5个HTML块元素标签

div、p、ul、li、table、h1、h2、h3 ... h6、form 等


07、请写出至少5个HTML行内元素标签

span、a、i、label、img、input、button、textarea、select 等


08、常用浏览器有哪些,内核都是什么?

常用浏览器有IE、火狐(firefox)、chrome、safari 、360、搜狗等
内核:


09、对 WEB 标准以及 W3C 的理解与认识

标签闭合、标签小写、不乱嵌套、提高搜索机器人搜索几率、使用外 链 css 和 js 脚本、结构行为表现的分离、文件下载与页面速度更快、内容能被更多的用户所访问、内容能被更广泛的设备所访问、更少的代码和组件,容易维 护、改版方便,不需要变动页面内容、提供打印版本而不需要复制内容、提高网站易用性。


10、前端需要注意哪些 SEO


11、Canvas 和 SVG 有什么区别?

Canvas 和 SVG 都允许您在浏览器中创建图形,但是它们在根本上是不同的。

通过 Javascript 来绘制 2D 图形。
是逐像素进行渲染的。
其位置发生改变,会重新进行绘制。

SVG
不依赖分辨率
支持事件处理器
最适合带有大型渲染区域的应用程序(比如谷歌地图)
复杂度高会减慢渲染速度(任何过度使用 DOM 的应用都不快)
不适合游戏应用


12、meta viewport 原理是什么?

meta viewport 标签的作用是让当前 viewport 的宽度等于设备的宽度,同时不允许用户进行手动缩放

viewport的原理:移动端浏览器通常都会在一个比移动端屏幕更宽的虚拟窗口中渲染页面,这个虚拟窗口就是 viewport; 目的是正常展示没有做移动端适配的网页,让他们完整的展示给用户;

解析:
Viewport :字面意思为视图窗口,在移动 web 开发中使用。表示将设备浏览器宽度虚拟成一个特定的值(或计算得出),这样利于移动 web 站点跨设备显示效果基本一致。移动版的 Safari 浏览器最新引进了 viewport 这个 meta tag,让网页开发者来控制 viewport 的大小和缩放,其他手机浏览器也基本支持。

在移动端浏览器当中,存在着两种视口,一种是可见视口(也就是我们说的设备大小),另一种是视窗视口(网页的宽度是多少)。
举个例子:如果我们的屏幕是 320 像素 * 480 像素的大小(iPhone4),假设在浏览器中,320 像素的屏幕宽度能够展示 980 像素宽度的内容。那么 320 像素的宽度就是可见视口的宽度,而能够显示的 980 像素的宽度就是视窗视口的宽度。

为了显示更多的内容,大多数的浏览器会把自己的视窗视口扩大,简易的理解,就是让原本 320 像素的屏幕宽度能够容下 980 像素甚至更宽的内容(将网页等比例缩小)。


13、Viewport 属性值


14、为什么最好把 CSS 的<link>标签放在<head></head>之间?为什么最好把 JS 的<script>标签恰好放在</body>之前,有例外情况吗?

<link>放在<head>

<link>标签放在<head></head>之间是规范要求的内容。此外,这种做法可以让页面逐步呈现,提高了用户体验。将样式表放在文档底部附近,会使许多浏览器(包括 Internet Explorer)不能逐步呈现页面。一些浏览器会阻止渲染,以避免在页面样式发生变化时,重新绘制页面中的元素。这种做法可以防止呈现给用户空白的页面或没有样式的内容。

<script>标签恰好放在</body>之前

脚本在下载和执行期间会阻止 HTML 解析。把<script>标签放在底部,保证 HTML 首先完成解析,将页面尽早呈现给用户。

例外情况是当你的脚本里包含document.write()时。但是现在,document.write()不推荐使用。同时,将<script>标签放在底部,意味着浏览器不能开始下载脚本,直到整个文档(document)被解析。也许,对此比较好的做法是,<script>使用defer属性,放在<head>中。


15、img 上 title 与 alt

title 指图片的信息、alt 指图片不显示时显示的文字


16、DOM Tree是如何构建的?

HTML 解释器
HTML 解释器的工作就是将网络或者本地磁盘获取的 HTML 网页和资源从字节流解释成 DOM 树结构。

JavaScript 的执行
在 HTML 解释器的工作过程中,可能会有 JavaScript 代码需要执行,它发生在将字符串解释成词语之后、创建各种节点的时候。这也是为什么全局执行的 JavaScript 代码不能访问 DOM 的原因——因为 DOM 树还没有被创建完呢。


17、video标签的几个个属性方法


18、script标签中defer和async的区别

defer 浏览器指示脚本在文档被解析后执行,script被异步加载后并不会立即执行,而是等待文档被解析完毕后执行

async 同样是异步加载脚本,区别是脚本加载完毕后立即执行,这导致async属性下的脚本是乱序的,对于script又先后依赖关系的情况,并不适用


19、meta标签常用属性

说明:告诉搜索引擎你网页的关键字(keywords)
使用方法:<meta name="keywords" content="标签,属性,seo优化">

说明:Robots用来告诉搜索机器人页面需要或者不需要索引。Content的參数有all、none、index、noindex、follow、nofollow。默认是all。

使用方法:<meta name="robots" content="All|None|Index|Noindex|Follow|Nofollow">

说明:viewport 是用户网页的可视区域,即“视区”。

使用方法:<meta name="viewport" content="width=device-width, initial-scale=1.0">

使用: <meta http-equiv = "X-UA-Compatible" content = "chrome=1" >

X-UA-Compatible:是IE8新加的一个设置,对于IE8以下的浏览器是不识别的,通过在meta中设置X-UA-Compatible的值,可以指定网页的兼容性模式设置。

< meta http-equiv = "X-UA-Compatible" content = "chrome=1" >用以声明当前页面用chrome内核来渲染。

Edge模式告诉IE以最高级 模式渲染文档,也就是任何IE版本都以当前版本所支持的最高级标准模式渲染,避免版本升级造成的影响。

使用:<meta name="renderer" content="webkit">

这段代码意思:强制浏览器使用Webkit内核。

若页面需默认用极速核,增加标签:<meta name="renderer" content="webkit">
若页面需默认用ie兼容内核,增加标签:<meta name="renderer" content="ie-comp">
若页面需默认用ie标准内核,增加标签:<meta name="renderer" content="ie-stand">

举例说明

a. 设置屏幕宽度为设备宽度,禁止用户手动调整缩放
<meta name="viewport" content="width=device-width,user-scalable=no" />

b. 设置屏幕密度为高频,中频,低频自己主动缩放,禁止用户手动调整缩放)
<meta name="viewport" content="width=device-width, target-densitydpi=high-dpi, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"/>

另外iOS 7.1的Safari为meta标签新增minimal-ui属性,在网页载入时默认隐藏地址栏与导航栏。


20、HTML5 为什么只需要写<!DOCTYPE HTML>,而不需要引入 DTD?

HTML5 不基于 SGML,因此不需要对 DTD 进行引用,但是需要 DOCTYPE 来规范浏览器的行为(让浏览器按照它们应该的方式来运 行)。
而 HTML4.01 基于 SGML ,所以需要对 DTD 进行引用,才能告知浏览器文档所使用的文档类型。


21、DTD 介绍

DTD( Document Type Definition 文档类型定义)是一组机器可读的规则,它们定义 XML 或 HTML 的特定版本中所有允许元 素及它们的属性和层次关系的定义。在解析网页时,浏览器将使用这些规则检查页面的有效性并且采取相应的措施。
DTD 是对 HTML 文档的声明,还会影响浏览器的渲染模式(工作模式)。


22、简述前端优化的方式


23、CSS盒子模型

盒模型分为标准盒模型怪异盒模型(IE模型)

/* 使用css指定某个元素的盒子模型类型 */
box-sizing:content-box;   /*标准盒模型*/
box-sizing:border-box;    /*怪异盒模型*/
01.png 02.png

上图显示:

在CSS盒子模型规定了元素处理元素的几种方式:

CSS盒模型和IE盒模型的区别:

在 标准盒子模型中,width 和 height 指的是内容区域的宽度和高度。增加内边距、边框和外边距不会影响内容区域的尺寸,但是会增加元素框的总尺寸。

IE盒子模型中,width 和 height 指的是内容区域+border+padding的宽度和高度。


24、为什么要初始化CSS样式。

因为浏览器的兼容问题,不同浏览器对有些标签的默认值是不同的,如果没对CSS初始化往往会出现浏览器之间的页面显示差异。


25、如何让一个div 上下左右居中?

<div class="div1"></div> 
/*给出三种css答案,实际上还有更多方法*/

/*方法一*/
.div1{
    width:400px;  
    height:400px;
    border:#CCC 1px solid;  
    /*下面几个才是居中的关键属性*/
    position:absolute;  
    left:50%;
    top:50%;   
    transform: translate(-50%,-50%); 
}  

/*方法二*/
.div1{ 
    width:400px;  
    height:400px;  
    border:#CCC 1px solid;  
    /*下面几个才是居中的关键属性*/
    position: absolute;  
    left:0;  
    top: 0;  
    bottom: 0;  
    right: 0;  
    margin: auto; 
}

/*方法三*/
.div1{ 
    width:400px;  
    height:400px;  
    border:#CCC 1px solid;
    /*下面几个才是居中的关键属性*/
    position: absolute;  
    left: 50%;  top:50%;  
    margin-left:-200px;  
    margin-top: -200px;  
}

26、简述css hack?

由于不同的浏览器,比如Internet Explorer 6,Internet Explorer 7,Mozilla Firefox等,对CSS的解析认识不一样,因此会导致生成的页面效果不一样,得不到我们所需要的页面效果。

这个时候我们就需要针对不同的浏览器去写不同的CSS,让它能够同时兼容不同的浏览器,能在不同的浏览器中也能得到我们想要的页面效果。

这个针对不同的浏览器写不同的CSS code的过程,就叫CSS hack,也叫写CSS hack。

CSS hack是通过在CSS样式中加入一些特殊的符号,让不同的浏览器识别不同的符号(什么样的浏览器识别什么样的符号是有标准的,CSS hack就是让你记住这个标准),以达到应用不同的CSS样式的目的,比如

.kwstu{width:300px;_width:200px;},

一般浏览器会先给元素使用width:300px;的样式,紧接着后面还有个_width:200px;,由于下划线_width只有IE6可以识别,所以此样式在IE6中实际设置对象的宽度为200px,后面的把前面的给覆盖了,而其他浏览器不识别_width不会执行_width:200px;这句样式,所以在其他浏览器中设置对象的宽度就是300px;


27、CSS 选择器有哪些?


28、css选择器的权重(优先级)

!important > 行内样式 > #id > .class > 元素和伪元素 > * > 继承 > 默认


29、CSS3新特性

转换


30、CSS隐藏元素的几种方法


31、css清除浮动的几种方式?


32、谈谈css预处理器的理解

CSS 预处理器定义了一种新的语言,其基本思想是,用一种专门的编程语言,为 CSS 增加了一些编程的特性,将 CSS 作为目标生成文件,然后开发者就只要使用这种语言进行编码工作。

CSS 预处理器用一种专门的编程语言,进行 Web 页面样式设计,然后再编译成正常的 CSS 文件,以供项目使用。CSS 预处理器为 CSS 增加一些编程的特性,无需考虑浏览器的兼容性问题

通俗的说,“CSS 预处理器用一种专门的编程语言,进行 Web 页面样式设计,然后再编译成正常的 CSS 文件,以供项目使用。CSS 预处理器为 CSS 增加一些编程的特性,无需考虑浏览器的兼容性问题”。

例如你可以在 CSS 中使用变量、简单的逻辑程序、函数(如右侧代码编辑器中就使用了变量$color)等等在编程语言中的一些基本特性,可以让你的 CSS 更加简洁、适应性更强、可读性更佳,更易于代码的维护等诸多好处。

CSS 预处理器技术已经非常的成熟,而且也涌现出了很多种不同的 CSS 预处理器语言,比如说:

到目前为止,在众多优秀的 CSS 预处理器语言中就属 Sass、LESS 和 Stylus 使用较为广泛。

优点:
1、CSS变得更易于维护。

2、易于编写嵌套选择器。

3、用于一致主题的变量。可以跨不同项目共享主题文件。

4、Mixins生成重复的CSS。

5、诸如循环,列表和映射之类的Sass功能可以使配置更容易且更省力。

6、将您的代码分成多个文件。CSS文件也可以拆分,但是这样做需要HTTP请求才能下载每个CSS文件。

缺点:
1、需要进行预处理的工具。重新编译时间可慢一些。

2、不编写当前和潜在可用的CSS。例如,通过将诸如 postcss-loader之类的内容 与 webpack一起使用,您可以编写可能与将来兼容的CSS,从而使您可以使用CSS变量(而不是Sass变量)之类的东西


33、请解释一下CSS3的flexbox(弹性盒布局模型),以及适用场景?

该布局模型的目的是提供一种更加高效的方式来对容器中的条目进行布局、对齐和分配空间。在传统的布局方式中,block 布局是把块在垂直方向从上到下依次排列的;而 inline 布局则是在水平方向来排列。弹性盒布局并没有这样内在的方向限制,可以由开发人员自由操作。
试用场景:弹性布局适合于移动前端开发,在Android和ios上也完美支持。


34、CSS 单位

最常用的单位:%百分比,px,rem,vh,vw

有传统的单位如:% 百分比、cm 厘米、mm 毫米、px 像素(计算机屏幕上的一个点)、in 英寸、pt 磅,此外还有:


35、有哪些方式可以对一个DOM设置它的CSS样式?


36、知道css有个content属性吗?有什么用?

CSS的content属性专门应用在before/after伪元素上,用来插入生成内容。最常见的应用是利用伪类清除浮动:

/*一种常见利用伪类清除浮动的代码*/
 .clearfix:after {   
    content:".";       /*这里利用到了content属性*/
    display:block;    
    height:0;   
    visibility:hidden;    
    clear:both; 
}   
  
.clearfix {    
    *zoom:1;    
}

after伪元素通过content在元素的后面生成一个点的块级元素,再利用clear: both清除浮动。


37、display 有哪些值?各有何作用?

常用的有以下(还有别的值,相对少用):


38、position 中的 relative 和 absolute 定位的区别?


39、用纯 CSS 创建一个三角形的原理是什么?

把上、左、右三条边隐藏掉(颜色设为 transparent)

#demo {
    width:0;
    height: 0;
    border-width: 20px;
    border-style: solid;
    border-color: transparent transparent red transparent;
}

40、什么是BFC?怎么创建BFC?

BFC(block formatting context)指块级格式化上下文。

BFC是一个独立的渲染区域,只有block-level box参与,它规定了内部的block-level box如何布局,并且与这个区域外部毫不相干。
    
BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之也如此,包括浮动和外边距合并等等,有了这个特性我们布局的时候就不会出现意外情况了

哪些元素会产生BFC
display属性为block、list-item、table的元素,会产生BFC。(最常用的就是块级元素)

什么情况下会触发BFC

BFC元素所具有的特性


41、什么叫优雅降级和渐进增强?

渐进增强 progressive enhancement:

针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果、交互等改进和追加功能达到更好的用户体验。

优雅降级 graceful degradation:

一开始就构建完整的功能,然后再针对低版本浏览器进行兼容。

区别:

a. 优雅降级是从复杂的现状开始,并试图减少用户体验的供给

b. 渐进增强则是从一个非常基础的,能够起作用的版本开始,并不断扩充,以适应未来环境的需要

c. 降级(功能衰减)意味着往回看;而渐进增强则意味着朝前看,同时保证其根基处于安全地带


42、什么是响应式设计?

它是关于网站的制作或网页制作的工作。不同的设备有不同的尺寸和不同的功能。响应式设计是让所有的人能在这些设备上让网站运行正常。一部分是媒体查询和不同的视觉效果。一部分是不同的资源(如不同的Javascript来处理触摸与点击自动适应屏幕的对比)


43、png,jpg,jpeg,gif,webp,bmp等图片格式?有哪些优缺点?

首先jpg和jpeg就可以理解为同一个东西,这里就只讲jpg。

优点:就是图片压缩后不至于太失真,色彩还原度较高

缺点:无法做透明图,就是没办法抠出一个图片

适用场景:基本上网页上的大图都是jpg

优点:能做透明图

缺点:体积大,如果色彩较多的,是同等jpg的5-6倍

适用场景:网页上的图标,一般都是用png24,png8有点半透明

优点:支持动画

缺点:颜色种类有限

适用场景:各种小动画。。

优点:简单说就是压得更小,图片质量却不差

缺点:兼容性差,IE和Safari不支持

适用场景:指定浏览器环境下可用

优点:高质量图片

缺点:太大了

适用场景:Windows桌面壁纸


44、聊聊Base 64图片

优点:减少http请求,因为图片被base64编码进了 css文件中(一般是进css文件)

缺点:如果加进css文件中去,css体积会增大,而且会阻塞渲染,(普通图片加载是异步的)

适用场景:适用于一些体积较小的图片


45、浏览器如何解析css选择器?

浏览器会『从右往左』解析CSS选择器。
我们知道DOM Tree与Style Rules合成为 Render Tree,实际上是需要将Style Rules附着到DOM Tree上,
因此需要根据选择器提供的信息对DOM Tree进行遍历,才能将样式附着到对应的DOM元素上。
以下这段css为例

.mod-nav h3 span {font-size: 16px;}

若从左向右的匹配,过程是:

从 .mod-nav 开始,遍历子节点 header 和子节点 div
然后各自向子节点遍历。在右侧 div 的分支中
最后遍历到叶子节点 a ,发现不符合规则,需要回溯到 ul 节点,再遍历下一个 li-a,一颗DOM树的节点动不动上千,这种效率很低。

如果从右至左的匹配:

先找到所有的最右节点 span,对于每一个 span,向上寻找节点 h3
由 h3再向上寻找 class="mod-nav" 的节点
最后找到根元素 html 则结束这个分支的遍历。

后者匹配性能更好,是因为从右向左的匹配在第一步就筛选掉了大量的不符合条件的最右节点(叶子节点);而从左向右的匹配规则的性能都浪费在了失败的查找上面


46、谈谈对媒体查询的理解

什么是媒体查询
媒体查询由媒体类型和一个或多个检测媒体特性的条件表达式组成。媒体查询中可用于检测的媒体特性有:width、height和color(等)。使用媒体查询可以在不改变页面内容的情况下,为特性的一些输出设备定制显示效果。通常用于多中设备适配屏幕。

媒体查询语法
如下面的例子,根据浏览器窗口大小的改变,页面颜色就会改变。

/*如果设备如果满足多个条件,以后面写的为准*/


/*屏幕尺寸最大为960px的屏幕下 */
@media screen and (max-width: 960px){
    body{
    background-color:#FF6699
    }
}

/*屏幕尺寸最大为768px的屏幕下 */
@media screen and (max-width: 768px){
    body{
    background-color:#00FF66;
    }
}


/*屏幕尺寸最大为550px的屏幕下 */
@media screen and (max-width: 550px){
    body{
    background-color:#6633FF;
    }
}

/*屏幕尺寸最大为320px的屏幕下 */
@media screen and (max-width: 320px){
    body{
    background-color:#FFFF00;
    }
}

47、flex弹性布局的使用

1.设置盒子的display属性为flex,或者line-flex,其对应还有六个css属性,分别为:

2. 对应的子元素项目也拥有自身的六个css属性,分别为:

设置flex布局后,子元素的float,clear,vertical-align都无效


48、 CSS优化、提高性能的方法有哪些?


49、一个满屏“品”字布局如何设计?


50、li 与 li 之间有看不见的空白间隔是什么原因引起的?有什么解决办法?

行框的排列会受到中间空白(回车空格)等的影响,因为空格也属于字符,这些空白也会被应用样式,占据空间,所以会有间隔,把字符大小设为0,就没有空格了。
解决方法:


51、javascript typeof返会的数据类型有哪些

object, string, undefined, number, function, boolean

js的基本数据类型:
string, number, boolean, undefined, null

数据类型检测:
typeof 对于基本数据类型来说,除了 null 都可以显示正确的类型,typeof 对于对象来说,除了函数都会显示 object

typeof 5 // 'number'
typeof '5' // 'string'
typeof undefined // 'undefined'
typeof false// 'boolean'
typeof Symbol() // 'symbol'
console.log(typeof null)  //object
console.log(typeof NaN)   //number

typeof [] // 'object'
typeof {} // 'object'
typeof console.log // 'function'

instanceof通过原型链来判断数据类型的

p1 = new Person()
p1 instanceof Person // true

Object.prototype.toString.call()可以检测所有的数据类型,算是一个比较完美的方法了。

var obj={}
var arr=[]
console.log(Object.prototype.toString.call(obj))    //[object Object]
console.log(Object.prototype.toString.call(arr))    //[object Array]

52、知道Array对象的哪些方法?

其中 push/pop/shift/unshift 初级考的最多。

不改变array的方法
var arr = [1, 2, 2];
arr.indexOf(1); //0
arr.indexOf(10); //-1
var arr = [1, 2, 2];
arr.lastIndexOf(2); //2
arr.lastIndexOf(10); //-1
var arr = [1, 2, 2, 5, 6];
arr.slice(2) // [2, 5, 6]
var arr = [1, 2, 2, 5, 6];
arr.slice(1,3) // [2, 2]
var arr = [1, 2, 2, 5, 6];
arr.slice();
var arr1 =  [1, 2, 3,4,5,6];
var arr2 = ['a','b','c'];
var arr3 = arr1.concat(arr2);
arr3;   //[1, 2, 3, 4, 5, 6, "a", "b", "c"]
var arr1 = [1, 2, 3];
var arr2 = arr1.concat(66,'abc',true,[10,20],[30,[31,32]],{x:100});
arr2;  //[1, 2, 3, 66, "abc", true, 10, 20, 30, [31,32], {x:100}]
var arr = [1, 2, 3];
arr.join('*')   //"1*2*3"
var arr = [1, 2, 3];
arr.join()   //"1,2,3"
var arr = [1, 2, 3];
arr.toString() // "1,2,3"

arr.map(function(elem, index, arr) {
    return elem * index;
}); 
//[0, 2, 6]
arr.map(function(elem, index, arr) {
    return elem * index;
}); 
//[0, 2, 6]
var arr = [1, 2, 3];
function log(element, index, array) {
    console.log('[' + index + '] = ' + element);
}
arr.forEach(log);
// [0] = 1
// [1] = 2
// [2] = 3
var arr = [1, 2, 3, 4, 5];
arr.filter(function (elem, index, arr) {
  return index % 2 === 1;
});
//[2, 4]
var arr = [1, 2, 3, 4];
arr.some(function (elem, index, arr) {
  return elem >= 3;
});
// true
var arr = [1, 2, 3, 4];
arr.every(function (elem, index, arr) {
  return elem >= 3;
});
// false
arr = [1, 2, 3]
arr.reduce(function(x, y){
  console.log(x, y)
  return x + y;
});
// 1 2
// 3 3
// 6
arr.reduceRight(function(x, y){
  console.log(x, y)
  return x + y;
});
// 3 2
// 5 1
// 6
改变原数组的方法
var arr = [1, 2];
arr.push(3) ;// 3
arr; //  [1, 2, 3]
arr.push('b','c'); //5
arr; //[1, 2, 3, "b", "c"]
arr.push([10,20]); //6
arr; //[1, 2, 3, "b", "c", [10,20]]
var arr =[1, 2, 3, "b", "c", [10,20]];
arr.pop(); //[10, 20]
arr;  // [1, 2, 3, "b", "c"]
var arr = [1, 2];
arr.unshift(3,4 );  //4
arr;  // [3, 4, 1, 2]
var arr = ['a', 'b', 1, 2];
arr.shift(); //'a'
arr;  //['b', 1, 2]
var arr = [1, 2, 12, 'a', 'b', 'ab', 'A', 'B']
arr.sort();  //[1, 12, 2, "A", "B", "a", "ab", "b"] 注意:12排在了2的前面

如果元素都是数字,要按从小到大排序,可以传入一个回调函数作为参数。

var arr = [1, 2, 12, 100]

arr.sort(function(a,b){
    return a-b;
});
// [1, 2, 12, 100]
var arr = [1, 2, 12, 'a', 'b', 'ab', 'A', 'B'];
arr.reverse();
//["B", "A", "ab", "b", "a", 12, 2, 1]
array.splice(start[, deleteCount[, item1[, item2[, ...]]]])

参数:start 为开始的索引,deletecount 表示要移除的数组元素的个数。item 为要添加进数组的元素

只删除,不添加。可以传入2个参数:

var arr = ['Alibaba', 'Tencent', 'Baidu', 'XiaoMi', '360'];

// 从索引2开始删除3个元素
arr.splice(2, 3); // 返回删除的元素 ['Baidu', 'XiaoMi', '360']
arr; // ['Alibaba', 'Tencent']

只添加,不删除。第2个参数设为0,即不删除元素。

arr.splice(2, 0, 'Toutiao', 'Meituan', 'Didi'); // 返回[],因为没有删除任何元素
arr; //["Alibaba", "Tencent", "Toutiao", "Meituan", "Didi"]

先删除若干元素,然后在删除的位置上在添加若干个元素。

var  arr =["Alibaba", "Tencent", "Toutiao", "Meituan", "Didi"]
arr.splice(2,2,'Apple','Google');  //["Toutiao", "Meituan"]
arr; //["Alibaba", "Tencent", "Apple", "Google", "Didi"]

53、JS如何实现一个类

function P(name, age){
     this.name = name;
     this.age= age;
   }
   P.prototype.sal= function(){
      
   }
   var pel= new P("jj", 1);
   pel.sell()
class Point {
       constructor(x, y) {
         this.x = x;
         this.y = y;
       }
       toString() {
         return '(' + this.x + ', ' + this.y + ')';
       }
     }
  var point = new Point(2, 3);

54、聊聊对js原型链的理解?

一句话解析什么是原型链:
遍历一个实列的属性时,先遍历实列对象上的属性,再遍历它的原型对象,一直遍历到Object
任何一个类(函数)都有原型对象,原型对象至少有两个属性(constructor,proto)。constructor指向函数本身,proto指向父类原型对象。

函数上有一个prototype属性,指向原型对象,通过它可以访问原型对象

函数的实列可以直接访问原型对象(因为实列上有proto指向构造函数的原型对象)

function Dog(){}        //类         
var obj=new Dog();      //实列
obj.name='沪江';
Dog.prototype.name="旺财";
Dog.prototype.eat=function(){
    console.log(this.name);
};
console.log(Dog.prototype.name);  //旺财
console.log(obj.prototype);      //undefined,prototype是类上才有的,实列上没有
obj.eat();                       //沪江(先遍历实列对象上的属性,再遍历它的原型对象)

55、变量声明提升?


56、作用域链?

因为函数的嵌套形成作用域的层级关系。当函数执行时,从当前作用域开始搜,没有找到的变量,会向上层作用域查找,直至全局函数,这就是作用域链。


57、作用域与执行上下文的区别


58、对象深拷贝、浅拷贝

对象浅拷贝是共用一个引用,因此更改新拷贝的对象时,也会更改原来的对象

对象深拷贝是两个引用,有以下几种方式实现深拷贝:


//使用 Object.assign,只能实现第一层属性的深拷贝
let clone = Object.assign({},obj)

//使用 slice,如果数组中有引用类型的元素的话,只能实现第一层的深拷贝
let clone = arr.slice(0);

//使用 concat,同 slice
let clone = [].concat(arr);

//使用 JSON 对象,无法实现属性值为 function 和 undefined 的拷贝,并且拷贝从原型链继承的值也会有问题,比如 constructor 的值变成了 Object
function deepClone(obj) {
  let _obj = JSON.stringify(obj);
  let clone = JSON.parse(_obj);
  return clone;
}

//使用递归,在不使用库的情况下,这种方式可以实现真正的深层度的拷贝
function deepClone(obj) {
  let clone = Array.isArray(obj) ? [] : {};
  if(obj && typeof obj === 'object') {
    for(let key in obj) {
      if(obj.hasOwnProperty(key) {
        if(obj[key] && typeof obj[key] === 'object') {
          clone[key] = deepClone(obj[key]);
        }else {
          clone[key] = obj[key];
        }
      }
    }
  }
  return clone;
}

//通过 JQuery 的 extend 方法
//使用 lodash 函数库

在使用 console.log 这类方法输出对象时会显示内存的最新状态,在同一个 tick 中,即便更改对象是在 console.log 之后,那么输出的对象也是被更改过的对象,因此,如果想输出某个时刻的对象值时,应该进行深拷贝进行输出。


59、for-in 和 for-of 的区别:

1、for-in 遍历的总是对象的下标,因此如果给数组增加属性,那么这个属性(key)也会遍历出来,更适合遍历对象,遍历顺序可能不是按照内部顺序,通常配合 hadOwnProperty() 方法一起使用;

2、for-of 就是迭代器,遍历的是数组元素的值,不会遍历增加的属性,是按照内部顺序遍历的,并且还可以遍历 Map 和 Set 数据结构。
如果没有在内部使用 let 那么默认为 var


60、图片懒加载、预加载


61、函数式编程

函数式编程中的函数指的数学概念中的函数,即自变量的映射,得到的结果由输入的值决定,不依赖于其他状态,是声明式(依赖于表达式),而非命令式,组合纯函数来构建软件的编程方式。


62、this 关键字

在全局环境中,this 指向 window 对象,ES5 函数中,this 对象是在运行时基于函数的执行环境(变量对象,如全局是 window),匿名函数的执行环境具有全局性,因此其 this 对象通常指向 window(在非严格模式下),在严格模式下 this 指向的是 undefined,为了在严格模式下,this 重新指向 window,可以使用非直接调用 eval 的方式,如 (0, eval)('this'),使用了逗号运算符,括号前面会返回 eval,但是和直接调用的区别就是在严格模式下 this 指向不一样。ES6 的箭头函数中,this 对象是在函数定义的执行环境。

this:上下文,会根据执行环境变化而发生指向的改变.

alert(this); // this -> window
function demo() {
 alert(this); // this -> window
}
demo();

在严格模式下,this是undefined.

function demo() {
 'use strict';
 alert(this); // undefined
}
demo();
function demo() {
 //alert(this); // this -> object
 this.testStr = 'this is a test';
}
let a = new demo();
alert(a.testStr); // 'this is a test'

function demo() {
 alert(this);
}
demo.call('abc'); // abc
demo.call(null); // this -> window
demo.call(undefined); // this -> window
setTimeout(function() {
 alert(this); // this -> window ,严格模式 也是指向window
},500)

window.onload = function() {
 let $btn = document.getElementById('btn');
 $btn.onclick = function(){
 alert(this); // this -> 当前触发
 }
}

window.onload = function() {
 let $btn = document.getElementById('btn');
 $btn.addEventListener('click',function() {
 alert(this); // window
 }.bind(window))
}
let name = 'finget'
let obj = {
 name: 'FinGet',
 getName: function() {
 alert(this.name);
 }
}
obj.getName(); // FinGet
//---------------------------分割线----------------------------
let fn = obj.getName;
fn(); //finget this -> window

62、栈和堆的区别?

栈(stack):由编译器自动分配释放,存放函数的参数值,局部变量等;

堆(heap):一般由程序员分配释放,若程序员不释放,程序结束时可能由操作系统释放。


63、JS中的匿名函数是什么?

匿名函数:就是没有函数名的函数,如:

(function(x, y){ alert(x + y); })(2, 3);

这里创建了一个匿名函数(在第一个括号内),第二个括号用于调用该匿名函数,并传入参数。


64、什么是事件代理/事件委托?

事件代理/事件委托是利用事件冒泡的特性,将本应该绑定在多个元素上的事件绑定在他们的祖先元素上,尤其在动态添加子元素的时候,可以非常方便的提高程序性能,减小内存空间。


64、什么是事件冒泡?什么是事件捕获?

冒泡型事件:事件按照从最特定的事件目标到最不特定的事件目标(document对象)的顺序触发。

捕获型事件:事件从最不精确的对象(document 对象)开始触发,然后到最精确(也可以在窗口级别捕获事件,不过必须由开发人员特别指定)。

在添加事件时用addEventListener(event,fn,useCapture)方法,基中第3个参数useCapture是一个Boolean值,用来设置事件是在事件捕获时执行,还是事件冒泡时执行。

注意:IE浏览器用attachEvent()方法,此方法没有相关设置,不过IE的事件模型默认是在事件冒泡时执行的,也就是在useCapture等于false的时候执行,所以把在处理事件时把useCapture设置为false是比较安全,也实现兼容浏览器的效果。


65、如何阻止事件冒泡?

w3c的方法是e.stopPropagation(),IE则是使用e.cancelBubble = true。例如:

window.event.cancelBubble = true;
e.stopPropagation();

66、如何阻止默认事件?

方法是e.preventDefault()


67、DOM 事件有哪些阶段?

js事件的三个阶段分别为:捕获、目标、冒泡

1.捕获:事件由页面元素接收,逐级向下,到具体的元素
2.目标:具体的元素本身
3.冒泡:跟捕获相反,具体元素本身,逐级向上,到页面元素

事件捕获:当使用事件捕获时,父级元素先触发,子元素后触发
事件冒泡:当使用事件冒泡时,子级元素先触发,父元素后触发


68、JS有哪些内置对象

Object是JavaScript中所有对象的父对象

数据封装对象:Object、Array、Boolean、Number和String
其他对象:Function、Arguments、Math、Date、RegExp、Error


69、解释jsonp的原理,以及为什么不是真正的ajax

答案:动态创建script标签,回调函数
Ajax是页面无刷新请求数据操作


70、null和undefined的区别?

null是一个表示"无"的对象,转为数值时为0;undefined是一个表示"无"的原始值,转为数值时为NaN。

当声明的变量还未被初始化时,变量的默认值为undefined。 null用来表示尚未存在的对象

undefined表示"缺少值",就是此处应该有一个值,但是还没有定义。典型用法是:

(1)变量被声明了,但没有赋值时,就等于undefined。

(2)调用函数时,应该提供的参数没有提供,该参数等于undefined。

(3)对象没有赋值的属性,该属性的值为undefined。

(4)函数没有返回值时,默认返回undefined。

null表示"没有对象",即该处不应该有值。典型用法是:

(1) 作为函数的参数,表示该函数的参数不是对象。

(2) 作为对象原型链的终点。


71、js延迟加载的方式有哪些?

defer和async、动态创建DOM方式(创建script,插入到DOM中,加载完毕后callBack)、按需异步载入js


72、js如何捕获异常?

try{
    //这里是可能出错并尝试捕获错误的代码
    doSomething();
}catch(e){
    //这里处理错误,e是错误信息,比如
    console.log(e)
}


73、解释AJAX的工作原理?


73、react和vue比较来说有什么区别


74、说一下vue实例的生命周期?

new Vue() > 初始化事件和生命周期 > beforeCreate > 数据绑定 > created > 如果有el属性,则编译模板 > beforeMount > 添加el属性,并替换掉挂载的DOM元素 > `mounted` > 数据更新 > `beforeUpdate` > 重新编译模板并渲染DOM > `updated` > 调用destoryed > beforeDestory > 销毁vue实例 > destroyed


75、vue双向数据绑定的原理是什么

首先传输对象的双向数据绑定 Object.defineProperty(target, key, decription),在decription中设置get和set属性(此时应注意description中get和set不能与描述属性共存)
数组的实现与对象不同。
同时运用观察者模式实现wather,用户数据和view视图的更新


76、new操作符具体干了什么呢?

1、创建一个空对象,并且 this 变量引用该对象,同时还继承了该函数的原型。

2、属性和方法被加入到 this 引用的对象中。

3、新创建的对象由 this 所引用,并且最后隐式的返回 this 。


77、如何防止出现中文乱码?

<meta charset="UTF-8"/>


78、DOM和BOM分别是什么?

浏览器的javascript的组成包含:

区别:

DOM 的 API :

子关系型
parent.childNodes() 返回一个即时的NodeList,包括了文本节点和注释节点
parent.children() 一个即时的HTMLCollection,子节点都是Element
parent.firsrtNode(),parent.lastNode(),hasChildNodes()

BOM的 API :


79、介绍下递归

在JavaScript程序中,函数直接或间接调用自己。通过某个条件判断跳出结构,有了跳出才有结果。

递归的步骤(技巧)

1、假设递归函数已经写好
2、寻找递推关系
3、将递推关系的结构转换为递归体
4、将临界条件加入到递归体中(一定要加临界条件,某则陷入死循环,内存泄漏)

例子(求1-100的和):


//普通循环写法
var sum = 0;
for(var i=1; i<=100; i++){
  sum += i;
}
console.log(sum); // 5050


//递归写法
function sum(n){
    if(n==1) return 1;
    return sum(n-1) + n;
}
var amount = sum(100);
console.log(amount); // 5050

81、JS的垃圾回收机制

JS 具有自动垃圾收集机制,执行环境会负责管理代码执行过程中使用的内存,所需内存的分配以及无用内存的回收完全实现了自动管理。垃圾收集机制的原理:找到那些不再继续使用的变量,然后释放其占用的内存。垃圾收集机制会按照固定的时间间隔周期性地执行这一操作。

垃圾收集机制必须跟踪哪个变量有用哪个变量无用,对于不再有用的变量打上标记,以备将来收回其占用的内存。

JS 中最常用的跟踪方法是标记清除,当函数执行完后,就会给局部变量打上“离开环境”的标记(除了闭包),在下一次垃圾回收时间到来时就会清除这一块内存,手动将一个有值的变量赋值为 null,也是让这个值离开环境,也可以释放内存。
还有一种跟踪方法是引用计数,这会引起循环引用的问题,但现在所有的浏览器都使用了标记清除式的垃圾回收机制,所以不用考虑这个问题了。


82、什么是MVVM? MVC? MVP?

mvc 的是 model view controller 的缩写,一种通过业务逻辑、数据、界面显示分离的方法进行代码组织的方法;其中 M 层处理数据、业务逻辑;v 层处理界面的显示结果;c 层起到桥梁的作用,来控制 v 层 和 M 层通信,以此达到分离视图显示和业务逻辑层;

mvp 是从 mvc 演化而来的,与 mvc 有一定的相似性, p 即 presenter 作为view 和 model 交互的桥梁纽带,处理与用户交互的逻辑;v 即 view 负责绘制 dom 元素、以及与用户的交互;model 负责存储、检索、操作数据;

mvp 和 mvc 的区别主要是:view 和 model 并不直接交互,而是通过与 presenter 交互来实现与 model 间接的交互;而在 mvc 中 view 和 model 是可以直接进行交互的;在 mvp 中,通常 view 和 presenter 是一对一的,但是复杂的 view 可能绑定多个 presenter 来处理逻辑;而在 mvc 中,controller 是基于行为层次的,并且可以被多个 view 共享,controller 可以负责决定显示那个 view;prresenter 与 view 的交互是通过接口来进行的;

mvp 的缺点就是增加了很多的接口和实现类,代码逻辑虽然清晰,但是代码量会比较大;

mvvm 是 mvp 的升级,其中 VM 是 viewModel 的缩写,可以理解成是 presenter和 view 的结合;viewModel 和 view 之间的交互不在是依赖于接口,而是通过 Data Binding 完成,而 Data Binding 可以实现双向的交互,从而使得视图和控制层之间的耦合度进一步的降低,分离更为彻底,同时减轻了 activity 的压力;


83、知道哪些主流前端框架

React、Vue、Angular、Antd、Element


84、在前端中什么是组件化 什么是模块化

组件化和模块化的价值都在于分治,web应用系统的复杂度不断提升,兼顾开发效率和产品实际运行效率,会在开发阶段运用组件化和模块化的手段分离关注点,结合构建工具合理打包。组件化更多关注的是UI部分,你看到的一个管理界面的弹出框,头部,内容区,确认按钮和页脚都可以是个组件,这些组件可以组成一个弹出框组件,跟其他组件组合又是一个新的组件。

模块化侧重于功能或者数据的封装,一组相关的组件可以定义成一个模块,一个暴露了通用验证方法的对象可以定义成一个模块,一个全局的json配置文件也可以定义成一个模块。封装隔离来后,更重要的是解决模块间的依赖关系。babel作为现在最火的es6转换器,用babelify或者webpack的babel loader再或者基于task的构建系统插件都可以很方便用起来es6 modules


85、介绍一下你对浏览器内核的理解

主要分成两部分:渲染引擎(layout engineer或Rendering Engine)和 JS 引擎。

最开始渲染引擎和 JS 并没有区分的很明确,后来JS引擎越来越独立,内核就倾向于只渲染引擎。


86、浏览器页面渲染过程

浏览器渲染页面的一般过程:

DOM树完全和html标签一一对应,但是渲染树会忽略掉不需要渲染的元素,比如head、display:none的元素等。而且一大段文本中的每一个行在渲染树中都是独立的一个节点。渲染树中的每一个节点都存储有对应的css属性。

以上四个步骤并不是一次性顺序完成的。如果DOM或者CSSOM被修改,以上过程会被重复执行。实际上,CSS和JavaScript往往会多次修改DOM或者CSSOM。


87、重排和重绘

部分渲染树(或者整个渲染树)需要重新分析并且节点尺寸需要重新计算。这被称为重排。注意这里至少会有一次重排-初始化页面布局。
由于节点的几何属性发生改变或者由于样式发生改变,例如改变元素背景色时,屏幕上的部分内容需要更新。这样的更新被称为重绘。


88、什么情况会触发重排和重绘

添加、删除、更新 DOM 节点
通过 display: none 隐藏一个 DOM 节点-触发重排和重绘
通过 visibility: hidden 隐藏一个 DOM 节点-只触发重绘,因为没有几何变化
移动或者给页面中的 DOM 节点添加动画
添加一个样式表,调整样式属性
用户行为,例如调整窗口大小,改变字号,或者滚动。


89、在浏览器中输入URL到整个页面显示在用户面前时这个过程中到底发生了什么

90、cookies,sessionStorage 和 localStorage 的区别


91、为什么会有同源策略

同源策略限制从一个源加载的文档或脚本如何与另一个源的资源进行交互。这是用于隔离潜在恶意文件的关键安全机制。

同源策略:协议相同、域名相同、端口相同,三者都必须相同

什么叫限制:不同源的文档不能操作另一个源的文档,在以下几个方面操作不了:

1)Cookie、localStorage、indexDB 无法读取
2)DOM 无法获得
3)AJAX 请求无法发送


92、HTTP有哪些请求方法?

HTTP1.0定义了三种请求方法: GET, POST 和 HEAD方法。

HTTP1.1新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。


93、HTTP get和post方法的区别?

1、GET请求,请求的数据会附加在URL之后,以?分割URL和传输数据,多个参数用&连接。URL的编码格式采用的是ASCII编码,而不是uniclde,即是说所有的非ASCII字符都要编码之后再传输。

POST请求:POST请求会把请求的数据放置在HTTP请求包的包体中。上面的item=bandsaw就是实际的传输数据。
因此,GET请求的数据会暴露在地址栏中,而POST请求则不会。

2、传输数据的大小

在HTTP规范中,没有对URL的长度和传输的数据大小进行限制。但是在实际开发过程中,对于GET,特定的浏览器和服务器对URL的长度有限制。因此,在使用GET请求时,传输数据会受到URL长度的限制。

对于POST,由于不是URL传值,理论上是不会受限制的,但是实际上各个服务器会规定对POST提交数据大小进行限制,Apache、IIS都有各自的配置。

3、安全性

POST的安全性比GET的高。这里的安全是指真正的安全,而不同于上面GET提到的安全方法中的安全,上面提到的安全仅仅是不修改服务器的数据。比如,在进行登录操作,通过GET请求,用户名和密码都会暴露再URL上,因为登录页面有可能被浏览器缓存以及其他人查看浏览器的历史记录的原因,此时的用户名和密码就很容易被他人拿到了。除此之外,GET请求提交的数据还可能会造成Cross-site request frogery攻击


94、http状态码

100-199:成功接收请求,但需要进行下一步请求
200-299:成功接收请求,并完成整个处理过程
300-399:为完成全部请求,客户需近一步细化需求
400-499:客户端请求有错误,包括语法错误或不能正常执行
500-599:服务器端出现错误


95、http与https有什么区别?

HTTP:是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和应答的标准(TCP),用于从WWW服务器传输超文本到本地浏览器的传输协议,它可以使浏览器更加高效,使网络传输减少。

HTTPS:是以安全为目标的HTTP通道,简单讲是HTTP的安全版,即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。

HTTPS协议的主要作用可以分为两种:一种是建立一个信息安全通道,来保证数据传输的安全;另一种就是确认网站的真实性。

HTTPS和HTTP的区别主要如下:


96、你常用的开发工具是什么,为什么?

vscode/chrome等;


97、说说最近最流行的一些东西吧?常去哪些网站?

Node.js、MVVM、Flutter、WebAssembly、Vue、Uni-app、React-native、Angular、Weex等

CSDN,Segmentfault,博客园,掘金,简书,Stackoverflow,伯乐在线,阮一峰的网络日志等


98、聊聊你的前端职业规划

推荐大家看看这篇文章:
写给前端应届生的职业规划建议


99、你如何看待加班?

这是一道半开放题. 没有准确答案,也不建议大家太主观地回答, 类似"加班是一种态度,不加班是一种能力,能力不够时就要展现我的态度!”算是不错的答案."

结合公司实际情况, 建议:

  1. 表现出自己过硬的工作实力,尽力避免由于自身问题导致被动型加班。
  2. 表现出自己谦虚的学习态度,愿意牺牲自己的一部分个人时间提升个人能力,以便日后更好工作。
  3. 表现出对公司和岗位的个人认识,通过面试前的准备,了解到求职岗位是否需要经常性加班,并表明是否接受。
  4. 表现出自己较高的效率意识,拒绝形式主义的加班和空耗时间。此条有风险视情况而定,如果在民营企业或是工作较为紧张的单位,可以这样讲,说不定会加分;如果在事业单位或是公务员,最好就不要提及啦。
  5. 根据个人情况的不同,表明个人对加班的其他看法。
  6. 最后也考虑(抖机灵)地考虑一下反问面试官,自己有哪里没有涉及到,或者还有哪些需要加班的场景呢?

100、面试官问“你还有什么问题”,应该怎么回答

开放问题, 最好不要回答"没有了"之类的话, 怎么回答也看情况看个人, 具体可以参考: 在面试的时候,快到最后了,技术面试官问你有什么要问他的吗,这时候应该怎么回答啊?

上一篇 下一篇

猜你喜欢

热点阅读