前端面试题及答案.全全全!!!

  小编真心地说一句,每个答案都问自己一下为什么???什么原因???你会理解的更透彻哦!!!面试更容易哦!!!

  HTML---CSS---JS---es6---Vue---微信小程序---浏览器---React---node---git---Typescript---webpack---前端设计模式

HTML面试题

1.DOCTYPE有什么作用?包标准模式和混杂模式如何区分?它们有什么意义?

告诉浏览器使用哪个版本的HTML规范来渲染文档。DOCTYPE不存在或形式不正确会导致HTML文档以混杂模式呈现。标准模式(Standards mode)以浏览器支持最高标准运行。混杂模式中页面是一种比较宽松向后兼容的方式显示。

2.什么是浏览器内核?

浏览器内核也就是浏览器所采用的渲染引擎,渲染引擎决定了浏览器如何显示网页的内容以及页面的格式信息。不同的浏览器内核对网页编写语法的解释也有不同,因此同一网页在不同的内核的浏览器里的渲染(显示)效果也可能不同,这也是网页编写者需要在不同内核的浏览器中测试网页显示效果的原因。

总结:浏览器内核也就是浏览器所采用的渲染引擎,渲染引擎决定浏览器如何显示页面,不同浏览器内核不同,所以显示网页的内容以及页面格式信息也就不同

3.介绍一下你对浏览器内核的理解?(不重要)

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

渲染引擎:负责取得网页的内容(HTML、XML、图像等等)、整理讯息(例如加入CSS等),以及计算网页的显示方式,然后会输出至显示器或打印机。浏览器的内核的不同对于网页的语法解释会有不同,所以渲染的效果也不相同。
JS引擎:解析和执行javascript来实现网页的动态效果。

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

4.常见浏览器内核有哪些?

1.Trident:IE,360,搜狗浏览器

2.Webkit:Safari Chrome

3.Geckos:FireFox Mozilla Suite/SeaMonkey

4.Presto:Opera7及以上(Opera内核原为:Presto,现为:Blink)

5.H5有哪些新特性?移除了哪些元素?如何却分HTML和HTML5?

新增元素

1.canvas(用于绘画)

2.用于媒体回放的video和audio元素

3.本地离线存储。localStorage长期存储数据,浏览器关闭后数据不丢失;sessionStorage的数据在浏览器关闭后自动删除

4.表单控件,calendar search datalist datetime output keygen date month week time color number range email url。

5.位置API:Geolocation

6.拖放API:drag、drop

7.语意化更好的内容元素,比如 article、footer、header、nav、section

移除元素:

纯表现的元素:

big(呈现大号字体效果)

font(规定文本的字体、字体尺寸、字体颜色)

<font size="3" color="red">This is some text!</font>
<font size="2" color="blue">This is some text!</font>
<font face="verdana" color="green">This is some text!</font>

u(文本添加下划线)

<p>如果文本不是超链接,就不要<u>对其使用下划线</u>。</p>

basefont   center  s strike tt

性能较差的元素:frame

区分:

DOCTYPE:告诉浏览器用哪个版本的HTML来渲染文档

<DOCTYPE html>

6.cookies,sessionStorage(html5)和localStorage(html5)的区别?

共同点:存储数据,,,都是本地存储

区别:

  1. localStorage长期存储数据,浏览器关闭数据后不丢失,用作长久数据 保存;
  2. sessionStorage数据仅在浏览器窗口关闭之前有效,关闭后自动删除;
  3. cookie在设置的cookie过期时间之前一直有效
  4. 存储大小的限制不同。cookie保存的数据很小,不超过4K。而sessionStorage和localStorage保存数据大,可达到5M
  5. cookie每次都会携带在HTTP头中,即cookies在浏览器和服务器之间来回传递,使用cookie保存过多数据会带来性能问题(cookie是网站为了标识用户身份而存储在用户本地终端(Client   Side)上的数据,始终在同源http请求中携带,即cookies在浏览器和服务器之间来回传递)。而sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存,不参与和服务器的通信(仅在客户端(即浏览器)中保存,不参与和服务器的通信)。----面试不用说,但是要知道
  6. 作用域不同。cookie在所有的同源窗口都是共享(不同浏览器、不同窗口中都是共享的:记住密码);sessionStorage不在不同的浏览器共享,即使同一页面(同一个浏览器、同站点不同窗口中可以共享);localStorage在所有同源窗口都是共享(仅同一个页面窗口中才能共享:购物车缓存)。----面试不用说,但是要知道

http://www.bubuko.com/infodetail-1813807.html

 为什么cookie每次都会携带在HTTP头中?

https://bbs.csdn.net/topics/330203634

https://blog.csdn.net/john1337/article/details/104571244?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2~all~sobaiduend~default-1-104571244.nonecase&utm_term=http%E4%B8%BA%E4%BB%80%E4%B9%88%E8%A6%81%E5%B8%A6cookie&spm=1000.2123.3001.4430

7.cookie 不设置过期时间,默认过期时间是多少?

关闭浏览器就结束了

8.iframe框架有哪些优缺点?(不重要)

优点:

  1. iframe能够原封不动的把嵌入的网页展现出来。
  2. 如果有多个网页引入iframe,那么你只需要修改iframe的内容,就可以实现调用的每一个页面内容的更改,方便快捷。
  3. 网页如果为了统一风格,头部和版本都是一样的,就可以写成一个页面,用iframe来嵌套,可以增加代码的可重用。
  4. 如果遇到加载缓慢的第三方内容如图标和广告,这些问题可以由iframe来解决。

缺点:

  1. 搜索引擎的爬虫程序无法解读这种页面
  2. 框架结构中出现各种滚动条
  3. 使用框架结构时,保证设置正确的导航链接
  4. iframe页面会增加服务器的http请求
  5. iframe页面必须先加载这部分内容,加载完成才加载其他的,影响用户体验

8.label的作用是什么?是怎么用的?(不重要)

label标签用来定义表单控件间的关系,当用户选择该标签时,浏览器会自动将焦点转到和标签相关的表单控件上。label中有两个属性是非常有用的,for

for属性功能:表示label标签要绑定的HTML元素,你点击这个标签的时候,所绑定的元素将获取焦点。例如,

​ <Label FOR="InputBox">姓名</Label><input ID="InputBox" type="text">

Label标签内for属性的值为自定义,一般与想实现点击会触发控件对象的ID对应相同。

HTML代码片段如下:
 <formaction=""method="get">
 性别:<br/>
 <inputname="sex"id="man"type="radio"value=""/>
 <labelfor="man">男</label>
 <inputname="sex"id="woman"type="radio"value=""/>
 <labelfor="woman">女</label>
 </form>
 注:input标签内id的值与label标签内for的值对应。

9.HTML5的form如何关闭自动完成功能?(不重要)

给不想要提示的input是设置autocomplete=off即可。

10.新的HTML5字符集是?

HTML5 使用 UTF-8 编码。

11.HTML5中如何嵌入音频?

audio标签

HTML5 支持 MP3、Wav 和 Ogg 格式的音频,下面是在网页中嵌入音频。

<audio src="htmls/1.mp3"  controls="controls">
你的浏览器不支持video元素
</audio>

src:播放音频的路径

controls:播放按钮 

12.HTML5中如何嵌入视频?

video标签

和音频类似,HTML5 支持 MP4、WebM 和 Ogg 格式的视频。

<video src="movie.ogg" controls="controls">
您的浏览器不支持 video 标签。
</video>

src:播放音频的路径

controls:播放按钮 

13.除了audio和video,HTML5还有哪些媒体标签?

HTML5 对于多媒体提供了强有力的支持,除了 audio 和 video 标签外,  标签定义嵌入的内容,比如插件。<embed>

<embed type=”video/quicktime” src=”Fishing.mov”>

  对于定义多个数据源很有用。  标签为诸如 <track>元素之类的媒介规定外部文本轨道。 用于规定字幕文件或其他包含文本的文件,当媒介播放时,这些文件是可见的。

<video width=”450″ height=”340″ controls>
     <source src=”W3Cschool.mp4″ type=”video/mp4″>
     <source src=”W3Cschool.ogg” type=”video/ogg”>
     <track kind=”subtitles” label=”English” src=”W3Cschool_en.vtt” srclang=”en” default></track>
      <track kind=”subtitles” label=”Arabic” src=”W3Cschool_ar.vtt” srclang=”ar”></track>
</video>

14.HTML5Canvas元素有什么用?

Canvas 元素用于在网页上绘制图形

属性:

getContext() 这个方法就是绘图的一个属性

beginPath():起始的一条路径

arc():创建弧,曲线

strock():绘制已定义的路径

fillStyle:用于填充绘画的颜色、渐变或模式

fillRect:绘制"被填充"的矩形

常用api

  1. fillRect(x,y,width,height)实心矩形
  2. strockRect(x,y,width,height)空心矩形
  3. fillText("Hello world",200,200):实心文字
  4. strokeText(“Hello world",200,300)空心文字

举例子: 

画圆:

<canvas id="myCanvas">
浏览器不支持 HTML5 canvas 标签
</canvas>
<script>
var c = document.getElementById("myCanvas")
var ctx = c.getContext("2d")
ctx.beginPath()
ctx.arc(95,50,40,0,2*Math.PI)
ctx.stroke()
</script>

画矩形:

<canvas id="myCanvas">
浏览器
</canvas>
<script>
var c = document.getElementById('myCanvas')
vat ctx = c.getContext('2d')
ctx.fillStyle = '#FF0000'
ctx.fillRect(0,0,80,100)
</script>

15.HTML5存储类型有什么区别?

HTML5 能够本地存储数据,在之前都是使用 cookies 使用的。HTML5 提供了下面两种本地存储方案: localStorage 用于持久化的本地存储,数据永远不会过期,关闭浏览器也不会丢失。 sessionStorage 同一个会话中的页面才能访问并且当会话结束后数据也随之销毁。因此sessionStorage不是一种持久化的本地存储,仅仅是会话级别的存储

loacalStorage:持久化存储,数据长期存在,只要不手动删除就不会销毁。也就相当于你给小明发语音,小明想什么时候听就可以什么时候听,除非他把你们的聊天记录删掉,才会销毁

sessionStorage:会话存储。就像两个人在谈话,谈话完成就OK了。也就相当于关闭浏览器后,数据也就销毁了

16.HTML5应用程序缓存和浏览器缓存有什么区别?

应用缓存最关键的就是支持离线应用,可获取少数或者全部网站内容,包括 HTML、CSS、图像和 JavaScript 脚本并存在本地。该特性加速了网站的性能,可通过如下方式实现:
<!doctype html>
<html manifest="example.appcache">
.....
</html>
与传统的浏览器缓存比较,该特性并不强制要求用户访问网站。

1.请至少写出5个HTML块级元素标签。

div,p,form,table,h1~h6,li,select,ol,ul,dl,dd

2.请至少写出5个行内元素标签。

span,img,input,button,a,label,dt

3.行内元素和块级元素的区别

  • 行内元素不可以设置宽高,不独占一行
  • 块级元素可以设置宽高,独占一行 

4.如何给行元素设置宽高 --行内元素设置为块级元素、脱离文档流

1.使用display:

display:block/inline-block/flex/inline-flex

<style>
        * {
            list-style: none;
            border: 0; 
            padding: 0;
            margin: 0
        }
        span { 
            width: 100px;    // 宽
            height: 100px;     // 高
            background: red; 
            text-align: center;
            line-height: 100px;
            display: block/inline-block/flex/inline-flex;     //display
        }
</style>
<span>1</span>

2.使用position

position:absolute/flex

<style>
        * {
            list-style: none;
            border: 0; 
            padding: 0;
            margin: 0
        }
        span {
            width: 100px; 
            height: 100px; 
            background: red; 
            text-align: center;
            line-height: 100px;
            position:absolate/fixed; 
        }
</style>
<span>1</span>

 3.使用float

float:left/right

<style>
        * {
            list-style: none;
            border: 0; 
            padding: 0;
            margin: 0
        }
        span {
            width: 100px; 
            height: 100px; 
            background: red; 
            text-align: center;
            line-height: 100px;
            float:left/right; 
        }
</style>
<span>1</span>

效果图:

https://www.cnblogs.com/kunmomo/p/10792968.html 

5.写出空元素。

<br> <hr> <link> <img> <input> <meta>

6.写出table标签下包含哪些标签元素。

tr,th,td,thead,tfoot,tbody

tr:表格中的行,tr 元素包含一个或多个 th 或 td 元素。

td:代表HTML表格中的一个单元格 

th:为表格标题

7.很多网站不用iframe,table这两个元素,为什么?

因为浏览器页面渲染从上向下加载的,用iframe和table这两个标签要先加载这两个标签的内容,加载完成在整体加载然后渲染,用户体验效果不好。

8.至少写出5个HTML5的新标签。

header,footer,nav,section,video

9.a标签在新窗口打开链接怎么加属性。

<a target="_blank"></a>

10.写了2个<a>标签,两个标签之间有空格的情况怎么解决。

将2个<a>标签写在一行里

11.DOCTYPE有什么作用?

告诉浏览器使用哪个版本的HTML文档渲染页面

12.页面导入样式时,link与import的区别。

  1. link方式的样式权重比import的权重高。
  2. link引用CSS时,在页面载入时同时加载;@import需要页面网页完全载入以后加载
  3. link支持js可以改变样式,而import不支持

13.如何区分html和html5。

  1. DOCTYPE的声明方式
  2. 根据新增加的结构,功能来区分

14.无样式内容闪烁?(FOUC)Flash Of Unstyle Content

FOUC:CSS样式最后才加载出来渲染html,因此会先看到混乱的网页在看到正常的网页

导致原因:

  1. 使用import导入样式
  2. 将样式表放在页面底部
  3. 使用import导入css

解决方法:使用link标签加载CSS样式文件。因为link是顺序加载的,这样的页面会等到CSS加载完成后再下载HTML文件,这样先布局好,然后就不会出现FOUC的问题了。

15.jpg和png的区别。(了解即可)

  • jpg:是有损所压缩格式,png是无损压缩格式。所以,相同的图片,jpg体积会小。
  • png:压缩比高,色彩好。
  • jpg:在www网站,用来存储和传输照片的格式

16.从浏览器地址栏输入url到显示页面的步骤

  • 浏览器根据请求的URL交给DNS域名解析,找到真实IP,向服务器发起请求;
  • 服务器交给后台处理完成后返回数据,浏览器接收文件(HTMLJSCSS、图象等);
  • 浏览器对加载到的资源(HTMLJSCSS等)进行语法解析,建立相应的内部数据结构(如HTMLDOM);
  • 载入解析到的资源文件,渲染页面,完成。

17.DNS域名解析

https://blog.csdn.net/qq_38218238/article/details/82425974 

CSS面试题

1.介绍一下标准的css的盒子模型?与低版本的IE盒子模型有什么不同?(重要)

标准盒子模型:宽度=内容的宽度(content)+ border + padding + margin

低版本的IE盒子模型:宽度=内容宽度(content+border+padding)+ margin

标准表型指的是设置box-sizing为content-box的盒子模型,一般width,height指的是content的宽高。IE盒模型指的是box-sizing为border-box的盒子。宽高的计算是content+padding+border;

box-sizing的css属性是用来改变默认的css框模型的,用来计算元素的宽度和高度,它可以使用这个属性来模拟浏览器的行为不正确支持css模型的规范

box-sizing属性

// 正常的
content-box(默认属性)
//IE:
border-box
// 从父元素继承 box-sizing 属性的值
inherit
  • css中box-sizing属性的值content-box的含义为:定义它的宽高的时候不包括border和padding
  • css中box-sizing属性的值border-box的含义为:定义它的宽高的时候包括border和padding,内容的宽高需要减去相应方向的border和padding。注意内容的宽和高必须保证不能为负必要时将自动增大该元素border box的尺寸以使其内容的宽或高最小为0。

怎么避免盒模型是低版本的IE盒模型?

答:将box-sizing属性设置为content-box

为什么box-sizing:border-box没有被广泛应用?

答:因为IE兼容性问题

举例子(理解)

https://www.imooc.com/qadetail/277827

https://zhidao.baidu.com/question/81427828.html

2.css框模型(box modal)

规定了元素框处理元素的内容(element),内边距(padding),边框(border)和外边距(margin)

注意margin:可以是负值,但是padding不可以,如果是负值就相当于把当前属性取消了

3.获取屏幕的高度和宽度 (屏幕分辨率): window.screen.height/width

4.css选择器有哪些?哪些属性可以继承?(重要)

CSS选择符:(只需要说前5个即可)

  • id选择器(#myid)、
  • 类选择器(.myclassname)、
  • 标签选择器(div, h1, p)、
  • 相邻选择器(h1 + p)、
  • 子选择器(ul > li)、
  • 后代选择器(li a)、
  • 通配符选择器(*)、
  • 属性选择器(a[rel=”external”])、
  • 伪类选择器(a:hover, li:nth-child)

相邻选择器:

<!DOCTYPE HTML>
<html>
<head>
<style type="text/css">
h1 + p {margin-top:50px;}
</style>
</head>

<body>
<h1>This is a heading.</h1>
<p>This is paragraph.</p>
<p>This is paragraph.</p>
<p>This is paragraph.</p>
<p>This is paragraph.</p>
<p>This is paragraph.</p>
</body>
</html>

子选择器:

<DOCTYPE html>
<head>
<title>子选择器</title>
<style type="text/css">
h1 > strong {
color: red
}
</style>
</head>
<body>
<h1>我是<strong>漂亮的</strong></h1>
</body>
</html>

后代选择器:

<html>
<head>
<style type="text/css">
h1 em {color:red;}
</style>
</head>

<body>
<h1>This is a <em>important</em> heading</h1>
<p>This is a <em>important</em> paragraph.</p>
</body>
</html>

属性选择器:

<!DOCTYPE html>
<html>
<head>
<style type="text/css">
[title]
{
color:red;
}
</style>
</head>

<body>
<h1>可以应用样式:</h1>
<h2 title="Hello world">Hello world</h2>
<a title="W3School" href="http://w3school.com.cn">W3School</a>

<hr />

<h1>无法应用样式:</h1>
<h2>Hello world</h2>
<a href="http://w3school.com.cn">W3School</a>
</body>
</html>

伪类选择器:链接的状态不同显示方式就不同

<html>
<head>
<style type="text/css">
a:link {color: #FF0000}  /* 未访问的链接 */
a:visited {color: #00FF00} /* 已访问的链接 */
a:hover {color: #FF00FF}  /* 鼠标移动到链接上 */
a:active {color: #0000FF} /* 选定的链接 */
</style>
</head>

<body>

<p><b><a href="/index.html" target="_blank">这是一个链接。</a></b></p>
<p><b>注释:</b>在 CSS 定义中,a:hover 必须位于 a:link 和 a:visited 之后,这样才能生效!</p>
<p><b>注释:</b>在 CSS 定义中,a:active 必须位于 a:hover 之后,这样才能生效!</p>

</body>
</html>

可继承的属性:

1、字体系列属性

  • font-family:字体系列
  • font-weight:字体的粗细
  • font-size:字体的大小
  • font-style:字体的风格

2、文本系列属性

  • text-indent:文本缩进
  • text-align:文本水平对齐
  • line-height:行高
  • word-spacing:单词之间的间距
  • letter-spacing:中文或者字母之间的间距
  • text-transform:控制文本大小写(就是uppercase、lowercase、capitalize这三个)
  • color:文本颜色

不可继承的样式padding, margin, width, height,border(只需要说前4个)

优先级(就近原则):!important >style >[ id > class > tag ]
注意:!important 比内联优先级高

!import>内联>ID选择器>类选择器=伪类选择器=属性选择器

!import的使用

<!DOCTYPE HTML>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>测试!Important</title>
</head>
<style type="text/css">
    #Box div
    {
        color: red;
    }
    .important_false
    {
        color: blue;
    }
    .important_true
    {
        color: blue !important;
    }
</style>
<body>
    <div id="Box">
        <div class="important_false">
            这一行末使用important</div>
        <div class="important_true">
            这一行使用了important</div>
    </div>
</body>
</html>

CSS代码第一行设定了box里面所有div中字体色为红色,第二行和第三行都用class重新定义了自身div的字体色为蓝色,

不同的是,第二行未使用!important,而第三行使用了!

5.CSS3新增伪类举例:(重要)

  1.   p:first-of-type 选择属于其父元素的首个 <p> 元素的每个 <p> 元素。
  2.   p:last-of-type 选择属于其父元素的最后 <p> 元素的每个 <p> 元素。
  3.   p:only-of-type 选择属于其父元素唯一的 <p> 元素的每个 <p> 元素。
  4.   p:only-child 选择属于其父元素的唯一子元素的每个 <p> 元素。
  5.   p:nth-child(2) 选择属于其父元素的第二个子元素的每个 <p> 元素。
  6.   :enabled :disabled 控制表单控件的禁用状态。
  7.   :checked 单选框或复选框被选中。

6.如何居中div?如何居中一个浮动元素?如何让绝对定位的div居中?(重要)

 div:margin: 0 auto; 上下边距为0,左右边距为auto,就是自动适应。

border: 1px solid red;
margin: 0 auto; 
height: 50px;
width: 80px;

浮动元素的上下左右居中:position: absolute;float: left;left: 50%;top: 50%;margin: -50px 0 0 -100px; 

border: 1px solid red;
float: left;
position: absolute;
width: 200px;
height: 100px;
left: 50%;
top: 50%;
margin: -50px 0 0 -100px; 

绝对定位的左右居中:position: absolute;margin: 0 auto;left: 0;right: 0;

border: 1px solid black;
position: absolute;
width: 200px;
height: 100px;
margin: 0 auto;
left: 0;
right: 0; 

利用绝对定位元素的自动伸缩特性水平垂直居中 

.father{
    position: relative;
    width: 500px;
    height: 500px;
}
.son{
    position:absolute;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    margin: auto;
}

利用flex布局水平垂直居中(回答这个显得更高端) 

#box{
    display: flex;
    display: -webkit-flex;
    border: 1px solid #0000FF;
    height: 200px;
    width: 400px;
    align-items:center;
    justify-content:center;
}
.item{
    width: 50px;
    height: 40px;
    border: 1px solid #00C1B3;
}

7. display有哪些值?说明他们的作用?(重要)

inline(默认)–此元素会被显示为内联元素,不换行

<style>
p {display:inline}
</style>

<p>这两个段落生成内联盒子,和它的结果</p>
<p>这两个元素之间没有距离。</p>

none–隐藏

<style>
h1.hidden {display:none;}
</style>
<h1>这是一个可见标题</h1>
<h1 class="hidden">这是一个隐藏标题</h1>
<p>注意, 实例中的隐藏标题不占用空间。</p>

block–块显示

inline-block-块级元素能够在同一行显示

able–表格显示

list-item–项目列表

8.position的值?(重要)

  • static(默认):按照正常文档流进行排列;
  • relative(相对定位):不脱离文档流,相对于自己 的父级
  • absolute(绝对定位):外面的父级,若没有父级,就是以左上角为准
  • fixed(固定定位):参照对象是浏览器窗口,出现滚动条的时候,不会随之滚动。

9. CSS3有哪些新特性?

  1. 文字阴影:text-shadow: 5px 5px 5px #FF0000;(水平阴影,垂直阴影,模糊距离,阴影颜色)
  2. 圆角(边框半径):border-radius 属性用于创建圆角
  3. 盒阴影:box-shadow: 10px 10px 5px #888888
  4. 边框图片:border-image: url(border.png) 30 30 round
  5. background-image background-origin(content-box/padding-box/border-box) background-size background-repeat
    word-wrap(对长的不可分割单词换行)word-wrap:break-word

10.请解释一下CSS3的flexbox(弹性盒布局模型)

以更加高效的方式来对容器进行布局,对其和分配空间.

11.用纯CSS创建一个三角形的原理是什么?(重要)

首先,需要把元素的宽度、高度设为0。然后设置边框样式

// tansparent  --背景透明

width: 0;
height: 0;
border-top: 40px solid transparent;
border-left: 40px solid transparent;
border-right: 40px solid transparent;
border-bottom: 40px solid #ff0000;

12.常见浏览器的兼容性问题?移动端兼容问题?

  1. 不同浏览器的标签默认的margin和padding不一样。*{margin:0;padding:0;}
  2. 标准表型指的是设置box-sizing为content-box的盒子模型,一般width,height指的是content的宽高。IE盒模型指的是box-sizing为border-box的盒子。宽高的计算是content+padding+border;
  3. IE6下在使用margin:0 auto;无法使其居中 。解决办法:为其父容器设置text-align:center;
    ========移动端=========
  4. 上下拉动滚动条时卡,慢:https://www.cnblogs.com/hrone/p/10143960.html
  5. body {
    // -webkit-overflow-scrolling:控制元素在移动设备上是否使用滚动回弹效果
    // touch:手指从触摸屏上移开,内容会继续保持一段时间的滚动效果
      -webkit-overflow-scrolling: touch;
      overflow-scrolling: touch;
    }
  6. 圆角bug,有些安卓手机圆角失效
    background-clip: padding-box;

    长时间按住页面闪退

  7. element {
      -webkit-touch-callout: none;
    }

    13.为什么要初始化CSS样式

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

14. display:none与visibility:hidden的区别?(元素隐藏)

  1. display:none 隐藏某个元素,且隐藏的元素不会占用任何空间
  2. visibility:hidden 隐藏某个元素,但隐藏的元素仍需占用与未隐藏之前一样的空间

15.为什么会出现浮动和什么时候需要清除浮动?清除浮动的方式?(重要)

浮动元素碰到包含它的边框或者浮动元素的边框停留。由于浮动元素不在文档流中,所以文档流的块框表现得就像浮动框不存在一样。浮动元素会漂浮在文档流的块框上。
浮动带来的问题:

  1. 父元素的高度无法被撑开,影响与父元素同级的元素
  2. 与浮动元素同级的非浮动元素(内联元素)会跟随其后
  3. 若非第一个元素浮动,则该元素之前的元素也需要浮动,否则会影响页面显示的结构。

清除浮动的方式:

  1. 给浮动元素父级div定义height
  2. 最后一个浮动元素后加空div标签 并添加样式clear:both。
  3. 包含浮动元素的父标签添加样式overflow为hidden或auto。
  4. 父级div定义伪类:after和zoom

16.设置元素浮动后,该元素的display值是多少?

自动变成display:block

17.使用 CSS 预处理器吗?

Less sass

18. CSS优化、提高性能的方法有哪些?(css优化性能的方法.)

  1. 避免后代选择符
  2. 避免不必要的重复代码
  3. 少使用!important

19.什么是响应式设计?响应式设计的基本原理是什么?如何兼容低版本的IE?(重要)

响应式网站设计是一个能够兼容多个终端而不是每一个终端做一个特定的版本

优点:一套代码兼容web端、平板、以及手机端网页

缺点:工作量大、UI设计也需要多个版本

场景:同时兼容多种不同设备
基本原理是通过媒体查询检测不同的设备屏幕尺寸做处理。
页面头部必须有meta声明的viewport。

<meta name="’viewport’" content="”width=device-width," initial-scale="1." maximum-scale="1,user-scalable=no”"/>

20.有一个高度自适应的div,里面有两个div,一个高度100px,希望另一个填满剩下的高度

外层div使用position:relative;高度要求自适应的div使用position: absolute; top: 100px; bottom: 0; left: 0

21.style标签写在body后与body前有什么区别?

页面加载自上而下 当然是先加载样式。
写在body标签后由于浏览器以逐行方式对HTML文档进行解析,当解析到写在尾部的样式表(外联或写在style标签)会导致浏览器停止之前的渲染,等待加载且解析样式表完成之后重新渲染,在windows的IE下可能会出现FOUC现象(即样式失效导致的页面闪烁问题)

22. CSS属性overflow属性定义溢出元素内容区的内容会如何处理?

overflow默认值visible

1.参数是scroll时,会出现滚动条

2.参数是hidden时,溢出隐藏

23.如何去除inline-blcok元素间隙?

空隙产生原因:HTML中的换行符、空格符、制表符等空白符,字体大小不为0的情况下,空白符占据一定宽度,使用inline-block会产生元素间的空隙。

解决办法:

  1. 把所有的子元素写在一行;
  2. 子元素设置浮动;
  3. 父元素的font-size设置为0,子元素的font-size设置为实际大小;

24.在不知道图片大小的情况下,如何设置样式让图片不变形?

max-width: 100%

25.link @import导入css(link和@import的区别)

  • link方式的样式权重比import的权重高。
  • link引用CSS时,在页面载入时同时加载;@import需要页面网页完全载入以后加载
  • link支持js可以改变样式,而import不支持

26.如何实现一个最大的正方形.

用 padding-bottom 撑开边距

 section {
    width:100%;
    padding-bottom: 100%;
    background: #333;
}

27.一行水平居中,多行居左

<div><span>我是多行文字。我是多行文字。我是多行文字。我是多行文字。我是多行文字。</span></div>
<div><span>我是一行文字</span></div>

<style>
div{text-align: center;}
div span{display: inline-block;
text-align: left;}
</style>

27.display:inline-block 什么时候会显示间隙?

  1. 有空格时候会有间隙 解决:移除空格
  2. margin正值的时候 解决:margin使用负值
  3. 使用font-size时候 解决:font-size:0、letter-spacing、word-spacing

28.相对长度和绝对长度的区别(重点) 

  • em指的是相对长度值是不固定的,而是由其他元素尺寸来决定的相对值,并且会继承父元素字体大小。相对单位长度指定了一个长度相对于另一个长度的属性。对于不同的设备相对长度更适用。相对长度还有:ex、ch、rem、vw、%等等。·
  • px是绝对长度单位它是一个固定的值是多少就是多少,不会因为其他元素的尺寸变化而变化。它反应一个真实的物理尺寸。绝对长度还有:cm、mm、in、pt等等。 
  • 相同点:px和em都是长度单位
  • 异同点:px的值是固定的,是多少就是多少,计算起来比较容易。em的值是不固定的,并且会继承父级元素的字体大小。
  • 浏览器默认字体高是16px。所以未经调整的浏览器都符合1em=16px。那么12px = 0.75em,10px = 0.625em

29.rpx与px的换算单位(重点)

1rpx = 0.5px

750物理像素

30.flex布局--容器属性;项目属性面试题(重点)

https://blog.csdn.net/qq_43413788/article/details/106005924

在css中,flex属性是使用来设置或检索弹性盒模型对象的子元素如何分配空间,3个属性:是 flex-grow属性、flex-shrink属性和 flex-basis 属性的简写属性。flex属性针对的是弹性盒模型对象的子元素,对于其它元素,flex属性不起任何作用;

注:如果元素不是"弹性盒模型对象的子元素",则 flex 属性不起作用。(弹性盒模型对象,即声明了display:flexdisplay: inline-flex的元素,这个元素被称为伸缩容器)

优点:简便、完整、响应式地实现各种页面布局

缺点:只兼容IE10+的浏览器

flex属性语法格式:

flex:flex-grow;flex-shrink;flex-basis/auto/initial/inherit

 1.flex布局flex-grow属性:

定义项目的放大(扩展)比例,即定义对剩余空间(如果有的话)的分配。对弹性容器内的元素,在当前列除自身宽度之外若还有剩余空间,而设定的分配

  • 默认为0,即如果存在剩余空间,也不放大。
  • 如果所有项目的flex-grow属性都为1,则它们将等分剩余空间。
  • 如果一个项目的flex-grow属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍。

下面这个示例比较全面,自行观察flex-grow设置为1、3、0的区别;以及设置为0但有内容和无内容的区别。

flex-shrink 

定义项目的收缩比例:对弹性容器内元素,如果所有子元素的宽的总和超过了弹性容器设定的宽width,那么该属性分配元素的收缩比例。

默认为1,即每个子元素收缩比例相同,但不会忽略内容(如果元素中的内容超过了容器的宽,那么容器会被撑开)

如果一个项目的flex-shrink属性为1,其他项目都为2,且所有项目的宽超过了容器设定的width,则所有项目的宽将在原基础进行收缩,后者进行收缩的量为前者的2倍。但是不会忽略内容,内容会占据实实在在的宽度。

flex-basis

  • flex-basis属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值auto,即项目的本来大小。
.item{
flex-basis:<length> | auto;
}
  • 和width不同。flex-basis用于设置或检索弹性盒伸缩基准值
  • 推荐这篇文章flex-basis表示在flex子元素 被放入flex容器之前的大小,是子元素的理想或者假设大小但是并不是其真实大小,其真实大小取决于flex容器的宽度、flex子元素的min-width,max-width等其他样式 

任何一个容器都可以指定为flex的布局.box{display:flex}

行内元素也可能使flex布局.box{display:inline-flex}

webkit内核的浏览器,必须加-webkit前缀

.box{display:-webkit-flex;/*Safari*/display:flex}

注意:设置弹性盒,子元素float,clear和vertical-align属性失效

flex-direction:排列方向             

row:从左往右
row-reverse:从右往左
column:从上到下
column-reverse:从下到上

flex-wrap: 是否换行         

nowrap(默认):不换行
wrap:换行
wrap-reserve

justify-content:定义了主轴的对其方式(横轴)

flex-start(默认):左对齐
flex-end:右对齐
center:居中
space-between:两端对齐,项目之间的间隔都相等
space-around:每个项目两侧的间隔相等

align-item:交叉轴上如何对齐。

flex-start:交叉轴的起点对齐。
flex-end:交叉轴的终点对齐。
center:交叉轴的中点对齐。
baseline: 项目的第一行文字的基线对齐。
stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。

order:属性定义项目的排列顺序。数值越小,排列越靠前,默认为0。

.item {
  order: <integer>;
}

flex-grow属性定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。

.item {
  flex-grow: <number>; /* default 0 */
}

https://www.jianshu.com/p/5856c4ae91f2

题:

flex--内容宽度等分

//css
       .box {
            display: flex;
        }
        
        .box div {
            flex: 1;
            border: 1px solid red;
        }
//html
    <div class="box">
        <div>1</div>
        <div>2</div>
        <div>3</div>
    </div>

31.滚动条

正常溢出部分会自动出现滚动条 

溢出隐藏:overflow:hidden

overflow:visible(默认)

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

  1.  单冒号(:)用于CSS3伪类,双冒号(::)用于CSS3伪元素。
  2. ::before就是以一个子元素的存在,定义在元素主体内容之前的一个伪元素。并不存在于dom之中,只存在在页面之中。
    :before 和 :after 这两个伪元素,是在CSS2.1里新出现的。起初,伪元素的前缀使用的是单冒号语法,但随着Web的进化,在CSS3的规范里,伪元素的语法被修改成使用双冒号,成为::before ::after

33.块级元素和行级元素有什么区别

 行内元素:

  • 与其他行内元素并排,行内元素不会自动换行
  • 不设置宽高,设置宽高无效,默认宽度就是文字宽度
  • 对margin设置左右方向有效,而上下无效,padding设置都有效

块级元素:

  • 自己独占一行,不能与其他元素并列
  • 可以自动换行,可以设置宽高,设置margin和padding都有效,如果不设置宽度,那么宽度将默认变为父级的100%

34.border:设置所有的边框属性 

p{border: 5px soild red;}
  •  border-width:边框宽度
  • border-style:边框样式
  • border-color:边框颜色
  • inherit:从父元素继承border属性的设置

35.百分比布局 (流式布局)也称为非固定像素布局

描述:页面元素的宽度按照屏幕分辨率进行适配调整,但整体布局不变。主要特征是像瀑布一样往下流,有规律的无限遍历模块。 

流式布局的方式是web移动端开发比较常见使用的一种方式

max-width:最大宽度               min-width:最小宽度

优点:灵活,充分利用浏览器的空间

缺点 :宽度按照屏幕进行适配调整,对于大屏幕来说用户体验并不是特别好,有些布局元素会显得很长

场景:类似抖音视频、微博消息、微信朋友圈等布局

36.水平居中的方法

  • 元素为行内元素,设置父元素text-align:center
  • 如果元素宽度固定,可以设置左右marginauto;
  • 如果元素为绝对定位,设置父元素positionrelative,元素设left:0;right:0;margin:auto;
  • 使用flex-box布局,指定justify-content属性为centerdisplay设置为tabel-ceil

37.垂直居中的方法 

  • 单行文本的话可以使用heightline-height设置同一高度。
  • position+margin:设置父元素:position: relative;,子元素height: 100px;position:absolute;top: 50%; margin: -50px 0 0 0;(定高)
  • position+transform:设置父元素position:relative,子元素:position: absolute;top: 50%;transform: translate(0, -50%);(不定高)
  • 百搭flex布局(ie10+),设置父元素display:flex;align-items: center;(不定高)

26如何实现左右等高布局

table布局兼容性最好,当然flex布局的align-items: stretch;也行

<div class="layout">
  <div class="layout left">left</div>
  <div class="layout right">center</div>
</div>

<style>
.layout{
  display: table;
  width: 100%;
}
.layout div{
  display: table-cell;
}
.layout .left{
  width: 50%;
  height: 200px;
  background: red;
}
.layout .right{
  width: 50%;
  background: yellow;
}
</style>
3.CSS优先级算法如何计算?(了解即可)

元素选择符: 1
class选择符: 10
id选择符:100
元素标签:1000

  1. !important声明的样式优先级最高,如果冲突再进行计算。
  2. 如果优先级相同,则选择最后出现的样式。
  3. 继承得到的样式的优先级最低。

13. CSS里的visibility属性有个collapse属性值?在不同浏览器下以后什么区别?(不重要)

当一个元素的visibility属性被设置成collapse值后,对于一般的元素,它的表现跟hidden是一样的。

  1. chrome中,使用collapse值和使用hidden没有区别。
  2. firefox,opera和IE,使用collapse值和使用display:none没有什么区别。

15. position跟display、overflow、float这些特性相互叠加后会怎么样?(了解即可)

display属性规定元素应该生成的框的类型;position属性规定元素的定位类型;float属性是一种布局方式,定义元素在哪个方向浮动。
类似于优先级机制:position:absolute/fixed优先级最高,有他们在时,float不起作用,display值需要调整。float 或者absolute定位的元素,只能是块元素或表格。

21.浏览器是怎样解析CSS选择器的?(不重要--理解就好)

CSS选择器的解析是从右向左解析的。若从左向右的匹配,发现不符合规则,需要进行回溯,会损失很多性能。若从右向左匹配,先找到所有的最右节点,对于每一个节点,向上寻找其父节点直到找到根元素或满足条件的匹配规则,则结束这个分支的遍历。两种匹配规则的性能差别很大,是因为从右向左的匹配在第一步就筛选掉了大量的不符合条件的最右节点(叶子节点),而从左向右的匹配规则的性能都浪费在了失败的查找上面。
而在 CSS 解析完毕后,需要将解析的结果与 DOM Tree 的内容一起进行分析建立一棵 Render Tree,最终用来进行绘图。在建立 Render Tree 时(WebKit 中的「Attachment」过程),浏览器就要为每个 DOM Tree 中的元素根据 CSS 的解析结果(Style Rules)来确定生成怎样的 Render Tree。

22.在网页中的应该使用奇数还是偶数的字体?为什么呢?(不重要)

使用偶数字体。偶数字号相对更容易和 web 设计的其他部分构成比例关系。Windows 自带的点阵宋体(中易宋体)从 Vista 开始只提供 12、14、16 px 这三个大小的点阵,而 13、15、17 px时用的是小一号的点。(即每个字占的空间大了 1 px,但点阵没变),于是略显稀疏。

23.margin和padding分别适合什么场景使用?(不重要)

何时使用margin:

需要在border外侧添加空白
空白处不需要背景色
上下相连的两个盒子之间的空白,需要相互抵消时。
何时使用padding:

需要在border内侧添加空白
空白处需要背景颜色
上下相连的两个盒子的空白,希望为两者之和。
兼容性的问题:在IE5 IE6中,为float的盒子指定margin时,左侧的margin可能会变成两倍的宽度。通过改变padding或者指定盒子的display:inline解决

兼容性的问题:在IE5 IE6中,为float的盒子指定margin时,左侧的margin可能会变成两倍的宽度。通过改变padding或者指定盒子的display:inline解决。

24. 元素竖向的百分比设定是相对于容器的高度吗?

当按百分比设定一个元素的宽度时,它是相对于父容器的宽度计算的,但是,对于一些表示竖向距离的属性,例如 padding-top , padding-bottom , margin-top , margin-bottom 等,当按百分比设定它们时,依据的也是父容器的宽度,而不是高度。

25.全屏滚动的原理是什么?用到了CSS的哪些属性?(不重要)

  1. 当按百分比设定一个元素的宽度时,它是相对于父容器的宽度计算的,但是,对于一些表示竖向距离的属性,例如 padding-top , padding-bottom , margin-top , margin-bottom 等,当按百分比设定它们时,依据的也是父容器的宽度,而不是高度。
  2. overflow:hidden;transition:all 1000ms ease;

28.你对line-height是如何理解的?(不重要)

行高是指一行文字的高度,具体说是两行文字间基线的距离。CSS中起高度作用的是height和line-height,没有定义height属性,最终其表现作用一定是line-height。
单行文本垂直居中:把line-height值设置为height一样大小的值可以实现单行文字的垂直居中,其实也可以把height删除。
多行文本垂直居中:需要设置display属性为inline-block。

29.怎么让Chrome支持小于12px 的文字?(不重要)

p{font-size:10px;-webkit-transform:scale(0.8);} //0.8是缩放比例

30.让页面里的字体变清晰,变细用CSS怎么做?(不重要)

-webkit-font-smoothing在window系统下没有起作用,但是在IOS设备上起作用-webkit-font-smoothing:antialiased是最佳的,灰度平滑。

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

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

  1. 可以将<li>代码全部写在一排
  2. 浮动li中float:left
  3. 在ul中用font-size:0(谷歌不支持);可以使用letter-space:-3px

34.png、jpg、gif 这些图片格式解释一下,分别什么时候用。有没有了解过webp?(不重要)

  1. png是便携式网络图片(Portable Network Graphics)是一种无损数据压缩位图文件格式.优点是:压缩比高,色彩好。 大多数地方都可以用。
  2. jpg是一种针对相片使用的一种失真压缩方法,是一种破坏性的压缩,在色调及颜色平滑变化做的不错。在www上,被用来储存和传输照片的格式。
  3. gif是一种位图文件格式,以8位色重现真色彩的图像。可以实现动画效果.
  4. webp格式是谷歌在2010年推出的图片格式,压缩率只有jpg的2/3,大小比png小了45%。缺点是压缩的时间更久了,兼容性不好,目前谷歌和opera支持。

44.水平垂直居中

两栏布局,左边固定,右边自适应,左右不重叠

flex做自适应布局很容易,但兼容性不好,这里统一不用flex布局

.left{
    float:left;
    width:300px;
    margin-right: 10px;
    background: red;
}
.right{
    overflow: hidden; /* 创建BFC */
    background: yellow;
}

46.BFC理解(BFC是什么?能解决什么问题?)

BFC触发条件:

  1. 根元素,即html
  2. float的值不为none(默认)
  3. position的值为absolute或fixed
  4. overflow的值不为visible(默认)
  5. display的值为inline-block、table-cell、table-caption

BFC特性:

  1. 内部的Box会在垂直方向上一个接一个放置。
  2. Box垂直方向的距离由margin决定,属于同一个BFC的两个相邻Box的margin会发生重叠。
  3. 每个元素的margin box 的左边,与包含块border box的左边相接触。
  4. BFC的区域不会与float box重叠。(可用于清浮动)
  5. BFC是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。
  6. 计算BFC的高度时,浮动元素也会参与计算。

BFC全称:Block Formatting Context,译为块级格式化上下文,它是CSS2.1规范定义的,关于CSS渲染定位的一个概念

能够解决因浮动造成的父元素塌陷问题

能够解决div浮动造成的遮盖问题【overflow:hidden; 触发bfc来解决遮挡问题】

JS面试题 

1.基本数据类型有哪几种?(高频)

undefined,null,boolean,string,number,Symbol(es6)

Symbol:定义对象的唯一标识(和id一样)

let name = Symbol()
console.log(typeof name)   // Symbol

2.引用数据类型有哪些?(高频)

Object,Array 

内建对象:Object,String,Array

3.JavaScript的typeof返回哪些数据类型(高频)

  •  undefined
  • string
  • boolean
  • number
  • symbol(ES6)
  • Object
  • Function

4.强制类型转换(高频)

原始数据类型(Number,string,boolean,null,undefined)

toString 

var a=1;
console.log(a.toString());//输出结果为黑色的1

 拼接字符串

var a=1;
var b=a+'';
console.log(b);//输出结果为黑色的1

使用Number

var a="123";
a=Number(a);
console.log(typeof  a);     结果:number

 如果:

var a="abc";
a=Number(a);
console.log(a);    结果:NaN

如果是纯数字的字符串,则直接转换为数字,如果字符串中有非数字的内容,则转换为NaN,如果字符串是一个空串或者是一个全是空格的字符串,则转换为0;

 Number(true)="1"     Number(Null)=0   Number(undefined)="NaN"

parseInt()   parseFloat()   专门用来对付字符串

var a = "123px";
a=parseInt(a);
console.log(typeof a);    结果:number
console.log(a);               结果:123 
var b=true;
b=parseInt(b);
console.log(typeof b);    结果:number
console.log(b);               结果:NaN

如果对非string使用parseInt()或parseFloat()它会先将其转换为string,然后再操作。 

转成boolean直接就用boolean;

除了0、NaN、空串、null、undefined其余都是true。对象也会转换为true

使用Boolean()函数
var a= 123;
a=Boolean(a);
console.log(typeof a);   结果:boolean
console.log(a);              结果:true

 https://blog.csdn.net/qq_40471415/article/details/88837412

https://blog.csdn.net/qq_41999617/article/details/81174185

5.隐式类型转换(高频)

== ===

扩展:通过==比较两边的值是否相等的结果?
1==’1’
null==undefined

6.“=="和“===”区别(高频)

前者会自动转换类型,在判断是否相等

后者不会自动转换类型,直接去比较

1==”1”
null==undefined;//==true

7.逻辑运算符:与,或,非

  • || : 只要其中有一个为true,整体结果是true; 
  • && : 只要有一个是false,整体结果是false; 
  • !:取 (比较:转布尔,在取反)

8.null和undefined是否相等?null和undefined的区别?(高频)

console.log(null==undefined)//true
console.log(null===undefined)//false

  null:

没有定义的时候是null值,报错是not found

nul表示"无",转成数值时为0

  undefined:
只是初始化,创建变量,但是没有赋值

undefined是一个表示"无"的原始值,转为数值时为NaN

9.JS四种检测(高频)

  1. typeOf:只能检测基本数据类型 
    typeof 1;//'number'
    typeof true;//'boolean'
    typeof '';//'string'
    typeof undefined;//'undefined'
    typeof function (){};'function'
    typeof null // Object
  2. instanceOf:检测当前实例是否属于某个类的方法 
    var arr = [];
    arr instanceof Array;//true
  3. constructor:检测属性是否存在于构造函数的原型上,用_proto_在原型上
    var arr = [];
    arr.constructor === Array;//true
  4. Object.prototype.toString.call([]); 最准确的方式;用来检测数据类型的
    console.log(Object.prototype.toString.call(1));//[object Number]
    console.log(Object.prototype.toString.call(''));//[object String]
    console.log(Object.prototype.toString.call(true));//[object Boolean]
    console.log(Object.prototype.toString.call(null));// [object Null]
    console.log(Object.prototype.toString.call(undefined));//[object Undefined]
    console.log(Object.prototype.toString.call([]));// [object Array]

    10.看下列代码,输出什么?解释原因。

var a = null;
alert(typeof a); //object

原理是这样的,不同的对象在底层都表示为二进制,在 JavaScript 中二进制前三位都为 0 的话会被判断为 object 类型, null 的二进制表示是全 0,自然前三位也是 0,所以执行 typeof 时会返回“ object ”。 

11.看下列代码,输出什么?解释原因。

var undefined;//此时undefined这个变量的值是undefined
undefined == null; // true
1 == true;   // true
此时会把布尔类型的值转换为数字类型 true=1 false=0
2 == true;   // false
0 == false;  // true
0 == '';     // true
NaN == NaN;  // false isNaN
[] == false; // true   解释:会把[]和false都通过Number()转换为数字类型
[] == ![];   // true   解释:![]:false
[]==[];//false

12.判断空字符串,undefiend,null

if(undefined == null){    }        //返回的是true

if(undefined == ' '){}                // 返回的是false

if(null == ' '){}                       // 返回的是false

控制台

' '为字符串

typeof null ==================> Object

typeof ' ' ====================> String

13.undefiend和null字符在if语句找那个,都会自动变成false =============>让他们变成true,前面要加!(取反)

 if(!null) == if(!undefined)  == true

14.Array,Object放在if语句中自动转成true(高频)

15.break,continue,return区别(高频)

  • break:立即结束语句,并跳出语句
  • continue:停止当前语句,并继续执行
  • return:停止函数
// break
for(var i = 0;i <= 10; i++){
    if(i == 6){
        break;
    }
    console.log(i);  //12345
}

// continue
for(var i = 0;i <= 10; i++){
    if(i == 6){
        continue;
    }
    console.log(i);  //1234578910
}

 16.for…in..和for…of..的区别?

for...in用于遍历数组或者对象的属性;;;;for...of遍历循环数组

for (变量 in 对象){  在此执行代码 }

var mycars = new Array()
mycars[0] = "Saab"
mycars[1] = "Volvo"
mycars[2] = "BMW"
mycars.color = "white"
for (var x in mycars)
{
   console.log(mycars[x]); //Saab Volvo BMW white
}
var mycars = {"1":"Saab", "2":"Volvo", "3":"BMW"};
mycars.color = "white" 
for (var x in mycars)
{
   console.log(mycars[x]);  //Saab Volvo BMW white
}

for of 遍历循环数组

for of遍历的只是数组内的元素,而不包括数组的原型属性method和索引name

var mycars = ["Saab", "Volvo", "BMW"]; 
mycars.color = "white" 
for (var x in mycars)
{
   console.log(mycars[x]);
}

17.map,forEach区别(高频)

相同点:

  1. 都是循环遍历数组中的每一项
  2. 每次执行匿名函数,都支持3个参数,参数分别是item(当前每一项),index(索引值),arr(原数组)
  3. 只能遍历数组
  4. 匿名函数中this都指向window 

不同点:map有返回值,不会改变原数组;forEach没有返回值,对原数组数据直接进行修改

map方法返回一个新的数组,数组中的元素为原始数组调用函数处理后的值(map()进行处理之后返回一个新的数组)

map方法不会改变原始数组

var arr = [0,2,4,6,8];
var str = arr.map(function(item,index,arr){
console.log(this); //Window
console.log(this);
console.log(item);
console.log('原数组arr:',arr); // 会执行五次
return item/2;},this);console.log(str); //[0,1,2,3,4]

forEach方法用于调用数组的每个元素,将元素传给回调函数

注意,forEach是不会返回有意义的值的。
我们在回调函数中直接修改arr的值。

arr.forEach((value, key) => {
 return arr[key] = value * value;
});

18.循环(while,do...while,for,for...in)(高频)

  • while 先判断--------->后执行
var i = 0;
while(i < 100){
console.log('i为' + i)
}
  • do......while 先执行------------->再判断
var x = 3;
var i = 1;
do {
console.log(i);
i++;
} while (i < x)
  • for循环
  • for...in    ---->用于对象遍历
var person = {name: "张”}
for(var key in person){
if(person.hasownproperty){
}
}
19.Number的方法
  • isNaN : 检查数字是否非法    // console.log(isNaN(123))   // false
  • Number :将其他数据类型的值强制转换成number类型; 
  • parseInt :经常用于字符串提取数字的方法; 
  • parseFloat:和parseInt 用法一样;区别是多识别一位小数点 
  • toFixed : 保留小数点位数的方法;返回值是一个字符串;

20.字符串的方法(13个)

  1. toUpperCase : 把小写字母转成大写 
  2. toLowerCase 把大写转小写 
  3. charAt : 通过索引获取字符 
  4. charCodeAt : 通过索引获取对应字符的Unicode编码; 
  5. substr : 截取 substr(m,n) 从索引m开始,截取n个字符; 
  6. substring: substring(m,n) :从索引m开始,截取到索引n,不包含n; (不支持负数) 
  7. slice(m,n): substring; 从索引m开始,截取到索引n,不包含n (支持负数) 
  8. indexOf : 检测字符在字符串中第一次出现的索引位置; 
  9. lastIndexOf : 检测字符在字符串中最后一次出现的索引位置; 
  10. split: 把字符串按照特定的字符分隔数组中的每一项; 
  11. replace:替换;原有字符串不变;用新字符替换旧的字符 
  12. concat : 拼接 

21.字符串的运算

- * /: 会先把字符串转换成数字,然后再进行计算

  1. 任何数字和NaN 计算,结果都是NaN;
  2. 任何数字和undefined运算,得到也是NaN;

22.split() join() 的区别(高频)

split():把一个字符串分割成字符串数组,并返回

“hello".split("")   // ["h", "e", "l", "l", "o"]

join():把数组中的所有元素放入一个字符串。元素是通过指定的分隔符进行分隔的,并返回

在本例中,我们将创建一个数组,然后把它的所有元素放入一个字符串:

<script type="text/javascript">
var arr = new Array(3)
arr[0] = "George"
arr[1] = "John"
arr[2] = "Thomas"

console.log(arr.join())

</script>
输出:

George,John,Thomas

23.js精度误差

  1. toFixed()方法
    使用不同函数分别计算(+,-,*,/)
    var a = 1;
    var b = 2.344544;
    consoel.log((a+b).toFixed(2))
    

    2.小数点[(变量 * 10) / 10])  先乘10再除以10

24.、获取元素的方法

  • document.getElementById:通过ID名来获取元素 
  • document.getElementsByTagName: 通过标签名来获取元素 
  • document.getElementsByClassName(); 类数组集合; 
  • document.getElementsByName;通过name属性来获取元素; 
  • document.documentElement 获取当前的html 
  • body :获取页面的body元素; 
  • document.querySelector();如果是id名加#,如果是class名加. 
  • document.querySelectorAll();获取所有的元素

25.DOM操作——怎样添加、移除、移动、复制、创建和查找节点。  

创建新节点

  • createDocumentFragment() // 创建一个DOM片段
  • createElement() // 创建一个具体的元素
  • createTextNode() // 创建一个文本节点

添加、移除、替换、插入

  • appendChild(node)
  • removeChild(node)
  • replaceChild(new,old)
  • insertBefore(new,old) // 在已有的子节点前插入一个新的子节点

查找

  • getElementsByTagName() // 通过标签名称
  • getElementsByName() // 通过元素的Name属性的值(IE容错能力较强,会得到一个数组,其中包括id等于name值的)
  • getElementById() // 通过元素Id,唯一性

26.DOM四种类型的节点 

TYPE nodeType nodeName nodeValue
元素节点 1 大写的标签名 null
文本节点 3 text 文本内容
注释节点 8 comment 注释内容
document 9 document null

空格和换行都是文本节点;

27.DOM节点的属性

  • childNodes : 获取当前元素所有的子节点; 
  • children : 获取当前元素的子元素节点; 
  • firstChild : 获取第一子节点; 
  • lastChild :获取最后一个子节点 
  • previousSibling : 获取上一个哥哥节点 
  • nextSibling : 获取下一个弟弟节点 
  • parentNode: 获取当前元素的父亲节点;

28.已知ID的Input输入框,希望获取这个输入框的输入值,怎么做?(不使用第三方框架)

document.getElementById("ID").value

29.怎么检测数组?

  1. instanceof
  2. isArray

注意: typeof 数组和Null 返回的是'Object'

30.改变数组长度的方法有哪些?

shift、unshift、pop、push

31.数组的方法(高频)

length():返回数组的长度

push()尾部添加,返回数组长度(向数组末尾新增一项;可以传多个)

var arr = ["Lily","lucy","Tom"];
var count = arr.push("Jack","Sean");
console.log(count); // 5
console.log(arr); // ["Lily", "lucy", "Tom", "Jack", "Sean"]

pop()尾部删除,返回被删除的元素(删除数组的最后一项;不需要传参数;)

var item = arr.pop();
console.log(item); // Sean
console.log(arr); // ["Lily", "lucy", "Tom", "Jack"]

unshift()头部添加 ,返回数组长度

var arr = ["Lily","lucy","Tom"];
var count = arr.unshift("Jack","Sean");
console.log(count); // 5
console.log(arr); //["Jack", "Sean", "Lily", "lucy", "Tom"]

shift()头部删除,返回被删除的元素

var item = arr.shift();
console.log(item); // Jack
console.log(arr); // ["Sean", "Lily", "lucy", "Tom"]

reverse():反转数组项的顺序

var arr = [13, 24, 51, 3];
console.log(arr.reverse()); //[3, 51, 24, 13]
console.log(arr); //[3, 51, 24, 13](原数组改变)

concat():数组的拼接 。构建成一个新的数组,原数组并未改变.

var arr = [1,3,5,7];
var arrCopy = arr.concat(9,[11,13]);
console.log(arrCopy); //[1, 3, 5, 7, 9, 11, 13]
console.log(arr); // [1, 3, 5, 7](原数组未被修改)

slice(m,n): 数组的截取 ,从数组索引m开始,截取到索引n,但是不包含n;[前包后不包] ,原有数组不发生改变
slice(m) : 从索引m开始,截取到末尾; 

slice()方法可以接受一或两个参数

var arr = [1,3,5,7,9,11];
var arrCopy = arr.slice(1);
var arrCopy2 = arr.slice(1,4);
var arrCopy3 = arr.slice(1,-2);
var arrCopy4 = arr.slice(-4,-1);
console.log(arr); //[1, 3, 5, 7, 9, 11](原数组没变)
console.log(arrCopy); //[3, 5, 7, 9, 11]
console.log(arrCopy2); //[3, 5, 7]
console.log(arrCopy3); //[3, 5, 7]
console.log(arrCopy4); //[5, 7, 9]

indexOf():接收两个参数:要查找的项和(可选的)表示查找起点位置的索引。其中, 从数组的开头(位置 0)开始向后查找
lastIndexOf:接收两个参数:要查找的项和(可选的)表示查找起点位置的索引。其中, 从数组的末尾开始向前查找
这两个方法都返回要查找的项在数组中的位置,或者在没找到的情况下返回-1。在比较第一个参数与数组中的每一项时,会使用全等操作符。

var arr = [1,3,5,7,7,5,3,1];
console.log(arr.indexOf(5)); //2
console.log(arr.lastIndexOf(5)); //5
console.log(arr.indexOf(5,2)); //2
console.log(arr.lastIndexOf(5,4)); //2
console.log(arr.indexOf("5")); //-1

 forEach()对数组进行遍历循环,对数组中的每一项运行给定函数。这个方法没有返回值。参数都是function类型,默认有传参,参数分别为:遍历的数组内容;第对应的数组索引,数组本身。

var arr = [1, 2, 3, 4, 5];
arr.forEach(function(x, index, a){
console.log(x + '|' + index + '|' + (a === arr));
});
// 输出为:
// 1|0|true
// 2|1|true
// 3|2|true
// 4|3|true
// 5|4|true

map()指“映射”,对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组。(有返回值)

var arr = [1, 2, 3, 4, 5];
var arr2 = arr.map(function(item){
return item*item;
});
console.log(arr2); //[1, 4, 9, 16, 25]

splice(m,n): 删除数组中的某几项 .从索引开始,删除n个 
splice(m) : 从索引m开始删除到末尾; 
splice(0): 
splice(m,x,n);替换从索引m开始,删除x个,用n替换; 
原有数组发生改变 

 sort():按升序排列数组项——即最小的值位于最前面,最大的值排在最后面。

在排序时,sort()方法会调用每个数组项的 toString()转型方法,然后比较得到的字符串,以确定如何排序。即使数组中的每一项都是数值, sort()方法比较的也是字符串,因此会出现以下的这种情况:

var arr1 = ["a", "d", "c", "b"];
console.log(arr1.sort()); // ["a", "b", "c", "d"]
arr2 = [13, 24, 51, 3];
console.log(arr2.sort()); // [13, 24, 3, 51]
console.log(arr2); // [13, 24, 3, 51](元数组被改变)

为了解决上述问题,sort()方法可以接收一个比较函数作为参数,以便我们指定哪个值位于哪个值的前面。比较函数接收两个参数,如果第一个参数应该位于第二个之前则返回一个负数,如果两个参数相等则返回 0,如果第一个参数应该位于第二个之后则返回一个正数。以下就是一个简单的比较函数:

function compare(value1, value2) {
if (value1 < value2) {
return -1;
} else if (value1 > value2) {
return 1;
} else {
return 0;
}
}
arr2 = [13, 24, 51, 3];
console.log(arr2.sort(compare)); // [3, 13, 24, 51]

如果需要通过比较函数产生降序排序的结果,只要交换比较函数返回的值即可:

function compare(value1, value2) {
if (value1 < value2) {
return 1;
} else if (value1 > value2) {
return -1;
} else {
return 0;
}
}
arr2 = [13, 24, 51, 3];
console.log(arr2.sort(compare)); // [51, 24, 13, 3]

filter()过滤”功能,数组中的每一项运行给定函数,返回满足过滤条件组成的数组。

var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var arr2 = arr.filter(function(x, index) {
return index % 3 === 0 || x >= 8;
}); 
console.log(arr2); //[1, 4, 7, 8, 9, 10]

every():判断数组中每一项都是否满足条件,只有所有项都满足条件,才会返回true。

var arr = [1, 2, 3, 4, 5];
var arr2 = arr.every(function(x) {
return x < 10;
}); 
console.log(arr2); //true
var arr3 = arr.every(function(x) {
return x < 3;
}); 
console.log(arr3); // false

some()

var arr = [1, 2, 3, 4, 5];
var arr2 = arr.some(function(x) {
return x < 3;
}); 
console.log(arr2); //true
var arr3 = arr.some(function(x) {
return x < 1;
}); 
console.log(arr3); // false

对象的方法? (高频)

  • concat():拼接字符串
  • slice():对字符串进行分割
  • split():把字符串分割成字符串数组 
  • toLowerCase():把字符串转换为小写
  • toUpperCase():把字符串转换为大写
  • charAt():返回指定字符的位置
  • indexOf():检索字符串
  • replace:替换与正则表达式匹配的字符串

32.数组的去重(高频)

1.new Set

const set = new Set([1, 2, 3, 4, 4]);
[...set]

2.双for循环

双层循环,外层循环元素,内层循环时比较值。值相同时,则删去这个值。

var arr = [1,2,3,4,5,6,54,5,67]
function unique(arr){
for(let i = 0; i< arr.length;i++){
for(let j = i + 1; j< arr.length;j++){
if(arr[i] == arr[j]){
  arr.splice(j,i)    // 第一个等同于第二个,splice方法删除第二个
}
}
}
return arr;
}

https://segmentfault.com/a/1190000016418021?utm_source=tag-newest

33.闭包:内部函数引用外部函数的变量(高频)

作用:延长它的生命周期

缺点:容易导致内存泄漏

var f=(function fn(){
    var name=1;
    return function(){
        name++;
        console.log(name);
    }
})();

function init(){
   var name="zhangsan";    // 创建局部变量name和局部函数alertName
   function alertName(){   //alertName()是函数内部方法,是一个闭包
        console.log(name)  //使用了外部函数声明的变量,内部函数可以访问外部函数的变量
    }
   alertName()
}
init()
34.JavaScript this、闭包、作用域(高频)
  • this:指向调用上下文
  • 作用域:定义一个函数就开辟了一个局部作用域,整个js执行环境有一个全局作用域
  • 闭包:内部函数调用外部函数里面的变量(例子如上)

35.闭包是什么,有什么特性,对页面有什么影响?为什么要用他?(高频)

闭包就是内部函数调用外部函数里面的变量
闭包的缺点:
1 更多的内存消耗
2.会造成内存泄露因为闭包中引用到的函数中定义的变量都永远不会被释放  解决:闭包在不使用的时候,及时释放。将引用内层函数对象的变量赋值为null。

为什么使用:

局部变量:仅函数内可用不会被污染

function a(){
    var n = 0;
    function add(){
       n++;
       console.log(n);
    }
    return add;
}
var a1 = a(); //注意,函数名只是一个标识(指向函数的指针),而()才是执行函数;
a1();    //1
a1();    //2  第二次调用n变量还在内存中

 36.函数(function)和方法(method)(高频)

区别:

  • 方法在对象里,方法也是函数
  • 函数可以随意调用

本质上是一样的,方法是函数的特例,将函数赋值给了对象
函数:可以实现一定功能的一段代码的封装

注意:函数创建后,在内存堆中以一段字符串文本存储,不执行时不会调用,就单单是存了一段字符串。

function f() {
 console.log('我是函数');   //调用函数 f();
} 

方法:把函数定义到对象里面就称为方法

var obj = {
 function f(){ 
console.log("我是方法"); 
} 
}; 
//对象调用方法 (对象调用通过点对象的属性名) obj.f();

37.简述创建函数的几种方式(高频)

第一种字面量(函数声明):

    语法:关键字  标识符   小括号  {函数体}

function sum1(num1,num2){
   return num1+num2;
}

第二种 表达式(匿名函数表达式):

    语法: 关键字  标识符 = function() 函数体

var sum2 = function(num1,num2){
   return num1+num2;
}

匿名函数:没有函数名称,无法通过函数名称调用

function(){}:只能自己执行自己

第三种(Function构造函数方式):

语法:   关键字   标识符  = new Function()

var sum3 = new Function("num1","num2","return num1+num2");

  注:内存栈:sum3:函数的引用

          内存堆:"num1","num2","return num1+num2",就是一个字符串

函数的三要素 :

函数名,参数,返回值(return)

返回值:每个函数都必须有return,如果没有return语句,计算机会自动在函数的最后一行补一个return,返回值为undefined。

38.什么是函数的封装?

把实现相同功能的代码放到一个函数体中,当想实现这个功能时,直接执行这个函数即可;减少了的冗余;高内聚,低耦合.

举例子:下订单

39.函数的执行过程(重要)

  1. 首先会形成一个私有的作用域
  2. 形参赋值
  3. 变量提升
  4. 代码从上到下运行;
  5. 作用域的销毁; 

在函数执行时,函数体中可以找到函数外面的变量;但是函数外面不能访问里面的变量;

40.构造函数与普通函数的区别

  1. 构造函数的的方法名首字母要大写,普通函数不需要。
  2. 构造函数的调用方法为: new  Show();普通函数:show()。
  3. 构造函数的类名和方法名一样;
  4. 构造函数要用this构造属性和方法;

构造函数   

// 定义构造函数
function Show(){
this.name = "张三"
this.age = "12"
}
var show = new Show()  // 调用构造函数
alert(show.name)    // 张三

// 普通函数

function show (name,age){
        this.name = zhangsanm;
        this.age = 12;
}
alert(show(this.name))   //zhangsanm

41.new 对象时发生了什么?

  • 初始化一个空对象
  • 绑定 this
  • 执行构造函数
  • 返回这个对象(不需要return来返回)

42.创建对象的方式有几种?(高频)

1.对象字面量(最常用的方式)

// 对象字面量创建了一个对象o1

var o1 = {
    p:"hello world",
    alertP:function(){
        alert(this.p);
    }
}

缺点 :每创建一个新的对象都需要写出完整的定义语句,不便于创建大量相同类型的对象,不利于使用继承等高级特性。

2.用new构造对象

function CO(){
    this.p = “I’m in constructed object”;
    this.alertP = function(){
        alert(this.p);
    }
}
var o2 = new CO();

https://www.cnblogs.com/lvmylife/p/5763214.html

43.call,apply,bind有什么作用?区别是什么?(高频)

考点:call和apply的用法

this指向有哪些?  call,apply,bind

call和apply相同点:改变函数中this的指向

不同点: 

 call和apply一样 只是传参数不一样 apply参数是以数组形式传的  bind和call传参方式一样 但是bind会立即执行

建议使用es6的箭头函数:这样就解决了this的指向问题

无参数调用:

function fn(){
    alert(this.name);
}
var p1={name:1};
fn.call(p1);
fn.apply(p1);

有参数调用:

function fn2(name,age){
    this.name=name;
    this.age=age;
}
var p1={};
fn2.call(p1,"张三",20);
fn2.apply(p1,["张三",20]);

44.形参(parameter)和实参(argument)的区别(高频)

  • 形参就是函数声明时的变量
  • 实参就是函数随时参入的具体参数
// a,b是形参,1,3是实参
function add(a,b){
return a+ b
}
add(1,3)

45.哪些操作会造成内存泄漏?

函数中使用的变量使用完后不会自动释放

  1. 闭包--(第四种情况是不合理的使用闭包,从而导致某些变量一直被留在内存当中。)
  2. setTimeout 的第一个参数使用字符串而非函数的话,会引发内存泄漏。(被遗忘的计时器或回调函数)--(第二种情况是我们设置了setInterval定时器,而忘记取消它,如果循环函数有对外部变量的引用的话,那么这个变量会被一直留在内存中,而无法被回收。)
  3. 意外的全局变量--(第一种情况是我们由于使用未声明的变量,而意外的创建了一个全局变量,而使这个变量一直留在内存中无法被回收。)

46.什么是 “use strict”; ? 使用它的好处和坏处分别是什么?

ECMAScript5中引入的严格模式,通过让JavaScript运行环境对一些开发过程中最常见和不易发现的错误做出和当前不同的处理,来让开发者拥有一个”更好”的JavaScript语言。

好处:

  • 消除Javascript语法的一些不合理、不严谨之处;
  • 提高编译器效率,增加运行速度;

好处具体体现:

  • 防止意外为全局变量赋值
  • 防止重名
  • 对只读属性修改时抛出异常

坏处:

  • 一些在“正常模式”下可以运行的语句,在“严格模式”下将不能运行;
  • 同样的代码,在“严格模式”中,可能会有不一样的运行结果;

47.你使用哪些工具和技术来调试 JavaScript 代码?(高频)

  1. alert
  2. console.log
  3. Debugger断点(具体的说就是通过在代码中添加”debugger;”语句,当代码执行到该语句的时候就会自动断点。)

 48.事件绑定和普通事件有什么区别

普通事件(onclick):直接触发事件,同一时间只能指向唯一对象,所以会被覆盖掉

var btn = document.getElementById("btn")
btn.onclick = function(){
    alter("你好111")
}
btn.onclick = function(){
     alter("你好222")
}

输出的结果只会有<你好222>,一个click处理器在同一时间只能指向唯一的对象。所以就算一个对象绑定了多次,其结果只会出现最后的一次绑定的对象。

事件绑定(addEventListener):事件绑定就是对于一个可以绑定的事件对象,进行多次绑定事件都能运行

var btn = document.getElementById("btn");
btn.addEventListener("click",function(){
	alert("你好111");
},false);
btn.addEventListener("click",function(){
	alert("你好222");
},false);

运行结果会依次弹出你好111,你好222的弹出框。

区别:

addEventListener对任何DOM都是有效的,而onclick仅限于HTML.

addEventListener可以控制listener的触发阶段,(捕获/冒泡)。对于多个相同的事件处理器,不会重复触发,不需要手动使用removeEventListener清除。

49.ajax请求时,如何解析json数据

json.parse 

50.阻止默认事件

return false

51.捕获异常的方法?(高频)

try{} catch(e){} finally(){}

52.ajax原理:

  1. 创建对象   var xhr = new XMLHTTPRequest()
  2. 打开请求  xhr.open('GET','example.txt',true)
  3. 发送请求  xhr.send()
  4. 接收响应数据  xhr.onready.stateChange = function()

53.什么是json

前后台交互的一种数据格式

54.怎样判断2个对象相等

JSON.stringfiy == JSON.stringify(obj)

55.ajax同步,异步的区别

async的值不同,分为同步和异步

同步async:false

异步async:true

56.Math的方法

  • Math.abs(): 取绝对值; 
  • Math.floor() : 向下取整 
  • Math.ceil() : 向上取整    console.log(Math.ceil(.95));     // 1
  • Math.max() : 取最大值    // console.log(Math.max(1,3,2)     //  3
  • Math.min() : 取一组数的最小值         // console.log(Math.min(1,3,2)    // 1
  • Math.random() 取随机数,取值范围[0,1) 
  • Math.round(): 四舍五入取整 
  • 取m-n之间的随机整数:Math.round(Math.random()*(n-m)+m) 
  • Math.pow() : 取幂次方 
  • Math.sqrt() : 开平方;

57.如何获取js中三个数的最大值和最小值

  • Math.max(a,b,c)    // 最大值
  • Math.min(a,b,c)     // 最小值

58.Date的实例

  • console.log(typeof new Date());
  • // "object"
  • console.log(new Date());
  • // 获取本机的系统时间;
  • var time = new Date();
  • console.log(time.getFullYear());
  • // 获取时间年;
  • console.log(time.getMonth())
  • // 获取时间月 取值范围【0-11】
  • console.log(time.getDate());
  • // 获取时间日【1-31】
  • console.log(time.getDay());
  • // 获取星期几;【0-6】 星期日是0;
  • console.log(time.getHours())
  • // 获取小时数 【0-23】
  • console.log(time.getMinutes());
  • // 获取分钟数 【0-59】
  • console.log(time.getSeconds());
  • // 获取时间秒【0-59】 console.log(time.getMilliseconds());
  • // 获取毫秒数【0-999】
  • console.log(time.getTime());
  • // 当前时间距离1970-1-1日早上八点的毫秒数;
  • console.log(Date.now());

59.输出今天的日期,以YYYY-MM-DD的方式,比如今天是2014年9月26日,则输出2014-09-26

考点:日期对象Date相关API的使用

var d = new Date();

60.设置定时器

1) setTimeout(cb,ms) 
2) setInterval(cb,ms)

相同点:全局函数在指定的毫秒(ms)内执行指定函数(cb) 

区别:

setTimeout(cb,ms) :只执行一次指定函数

function printHello(){
    console.log( "Hello, World!");
}
// 两秒后执行以上函数
var timer = setTimeout(printHello, 2000);

//清除定时器
clearTimeout(timer)

 setInterval(cb,ms)方法会不同的调用,知道clearInterval()被调用或关闭窗口

function printHello(){
   console.log( "Hello, World!");
}
// 两秒后执行以上函数
var timer = setInterval(printHello, 2000);

// 清除定时器
clearInterval(timer);

61.清除定时器

1) clearTimeout() 
2) clearInterval()

62.js延迟加载的方式有哪些?

js 的加载、解析和执行会阻塞页面的渲染过程,因此我们希望 js 脚本能够尽可能的延迟加载,提高页面的渲染速度。 

  1. 使用setTimeout延迟方法
  2. 让js最后加载(把js外部引入的文件放到页面底部,来让js最后引入,从而加快页面加载速度)
  3. 加loading
  4. 给 js 脚本添加 defer属性,这个属性会让脚本的加载与文档的解析同步解析,然后在文档解析完成后再执行这个脚本文件,这样的话就能使页面的渲染不被阻塞。多个设置了 defer 属性的脚本按规范来说最后是顺序执行的,但是在一些浏览器中可能不是这样。
  5. 给 js 脚本添加 async属性,这个属性会使脚本异步加载,不会阻塞页面的解析过程,但是当脚本加载完成后立即执行 js脚本,这个时候如果文档没有解析完成的话同样会阻塞。多个 async 属性的脚本的执行顺序是不可预测的,一般不会按照代码的顺序依次执行。
  6. 动态创建 DOM 标签的方式,我们可以对文档的加载事件进行监听,当文档加载完成后再动态的创建 script 标签来引入 js 脚本。

63.看代码给答案。

var a = new Object();  // 引用数据类型
a.value = 1;
b = a; //b.value=1
b.value = 2;//b.value=2;a.value=2,因为a和b指向同一块引用类型的值
alert(a.value);

答案:2

var a = 1;//基本数据类型
b = a;
b = 2;
console.log(a)

答案:1 

64.看下列代码,将会输出什么?

考点:1、变量作用域 2、变量声明提升

var foo = 1;
function f(){
    console.log(foo);  // 它只会找函数里面最近的,代码从上往下加载,所以是undefined
    var foo = 2;
    console.log(foo);     // 2
}
f();

输出undefined 和 2。

65.foo = foo||bar ,这行代码是什么意思?为什么要这样写?

var foo;
if(foo){
    foo=foo;
}else{
    foo=bar;
}

答案:常用于函数参数的空判断
短路表达式:作为”&&”和”||”操作符的操作数表达式,这些表达式在进行求值时,只要最终的结果已经可以确定是真或假,求值过程便告终止,这称之为短路求值。
考点:if条件的真假判定
记住以下是false的情况:空字符串、false、undefined、null、0

66.请解释同步 (synchronous) 和异步 (asynchronous) 函数的区别。(高频),怎么解决异步问题(高频)

举例子:

同步:如果在同一时间内有很多任务的话,这些任务需要排队,一个一个的执行,前一个任务执行完,才会执行下一个任务.

// 同步代码
function fun1() {
  console.log(1);
}
function fun2() {
  console.log(2);
}
fun1();
fun2();

// 输出
1
2

异步:如果在同一时间内有很多任务的话,这些任务不需要排队就可以去完成.任务都完成就结束了(我昨天是不是就是这样说的?公交车那个)

67.javascript的同源策略;跨域? (高频)

同源策略:协议,域名,端口相同
http,ftp:协议
关键词解释:
域名:localhost、www.baidu.com
协议:http https ftp
端口:一个网站对应着一个端口, http协议的默认端口:80
https协议的默认端口是8083
同源策略带来的麻烦:ajax在不同域名下的请求无法实现,

如果说想要请求其他来源的js文件,或者json数据,那么可以通过jsonp来解决

跨域:指的是浏览器不能执行其他网站的脚本。是由浏览器的同源策略造成的,是浏览器对js施加的安全限制。
跨域解决方式一

通过CORS解决(最常用的方案,安全,可靠)

跨域资源共享CORS(Cross-Origin Resource Sharing):属于跨源AJAX请求的根本解决方法

xhrFields.withCredentials = true   // 前端设置是否带cookie

1.普通跨域请求:只需服务端设置Access-Control-Allow-Origin

2.带cookie跨域请求:前后端都需要进行设置

//java中的 hander() 设置,“*”号表示允许任何域向我们的服务端提交请求:
    header("Access-Control-Allow-Origin: *")

3.通过jsonp跨域:服务器与客户端跨源通信的常用方法

  • 优点:简单适用,兼容性好
  • 缺点:只支持get请求,不支持post请求。
// Vue
this.$http.jsonp('http://www.domain2.com:8080/login',{
    params:{},
    jsonp:'handleCallback'
}).then((res) =>{
    console.log(res)
})

3.nginx代理跨域 

4.nodejs中间件代理跨域

68.js(es5)类:用的构造函数;es6类用的:class类(高频)

es5: 

  • 获取对象: new 类名称()
  • 访问:对象.成员

es6:

 function 类名称(){...}   // 与方法不同的是:类名称首字母要大写

// es5 定义类的方法 向类中添加属性
function Person(name){
    this.name = name;        // 在类内部定义一个属性
    this.say = function(){ alter(this.name)}
}
var p1 = new Person('zh')
p1.say()
alert(typeof (p1));//object
alert(typeof (Person('zhh')));//Undefined 函数没有返回值则为Undefined
alert(typeof(Person));//function


// es6 通过class关键字 定义类
class Point{
    constructor(x,y){
        this.x = x;
        this.y = y;
    }
    toString(){
        return '(' + this.x + ',' + this.y + ')'
    }
}
 //第一种定义类的方法,类中增加属性
    function Person(name) {
       this.Name = name;//在类内部定义一个属性
       this.say = function () {
         alert(this.Name);
     }
    };
    var p1 = new Person('zhh');
       p1.say();
       alert(typeof (p1));//object
       alert(typeof (Person('zhh')));//Undefined 函数没有返回值则为Undefined
       alert(typeof(Person));//function

class类:

1.通过class关键字,可以定于类

//定义类
class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  toString() {
    return '(' + this.x + ', ' + this.y + ')';
  }
}

上面代码定义了一个“类”,可以看到里面有一个constructor方法,这就是构造方法,而this关键字则代表实例对象。也就是说,ES5的构造函数Point,对应ES6的Point类的构造方法。

3、定义“类”的方法的时候,前面不需要加上function这个关键字,直接把函数定义放进去了就可以了。另外,方法之间不需要逗号分隔,加了会报错。 

4.构造函数的prototype属性,在ES6的“类”上面继续存在。事实上,类的所有方法都定义在类的prototype属性上面。

class Point {
  constructor(){
    // ...
  }

  toString(){
    // ...
  }

  toValue(){
    // ...
  }
}

// 等同于

Point.prototype = {
  toString(){},
  toValue(){}
};

5、Object.assign方法可以很方便地一次向类添加多个方法。

class Point {
  constructor(){
    // ...
  }
}

Object.assign(Point.prototype, {
  toString(){},
  toValue(){}
});

https://www.cnblogs.com/zcl997136048/p/9283687.html 

69.js的三大特性:继承,封装,多态

1.封装:是一个公共的方法

是当你需要隐藏一些属性和方法时,就可以将这些属性和方法封装起来,然后通过一个外部可以调用的特定接口进行调用。

function Person(name , age , sex){
    this.name = name ; //共有变量 
    var age = age ;  //私有变量
    var sex = sex ; //私有变量
    this.show = function (){
        console.log(age+"===="+sex);
    }
}
var person = new Person('Sunshine',18,'女');
console.log(person.age);    // undefined
console.log(person.name);   // Sunshine
console.log(person.show());     // 18====女

请看代码后的注释,this指向的都是共有的属性和方法,而直接通过var声明的则属于私有变量(即外部不可访问变量),然后通过一个共有的show方法将私有的age和sex输出。当然show方法也要通过this声明才可以哟,否则的话show方法也是不可访问的。 

好处:

  • 提高代码复用性
  • 解耦
  • 提高网站的打开速度

2.继承:

就是当多个方法存在相同的属性和方法时,就把这些相同的属性和方法提取到一个公共的方法中,通过原型prototype继承该方法。当然你也可以通过call或apply来继承该方法中的属性和方法。

function Person(name , age , sex){
    this.name = name ; 
    this.age = age ; 
    this.sex = sex ; 
    this.show = function (){
        console.log( this.age + "========"+ this.sex );
    }
}
function Student(name , age , sex , score){
    this.score = score ; 
    Person.apply(this,[name , age , sex]);
}
function Worker(name , age , sex , job){
    this.job = job ; 
    Person.call(this,name , age , sex);
}
Dancer.prototype = new Person('Sunshine',18,'女');
function Dancer(salary ){
    this.salary = salary ;
}
var student = new Student('Sunshine',18,'女',100);
var worker = new Worker('Sunshine',18,'女','IT');
var dancer = new Dancer(20000);
console.log(student);
console.log(worker);
console.log(dancer);

当然,个人感觉那个prototype没有说的很好,如果看到这篇博客的你有更好的建议或意见的话,欢迎给我留言。还有call和apply,其实它们的作用是一样的,都是改变this指向,然后它们的区别也可以从代码中看出,传参方式不同。

3.多态 :

多态就是在执行同一操作且作用于不同对象时,返回不同的结果 。其实也就是把做什么和由谁去做分开,这样使得代码更容易维护,且条例清晰。直接上例子吧:

function dwn(s){
    document.write(s+"<br/>");
}
function Animal(){
    this.bite=function(){
        dwn("animal bite!");
    }
}
function Cat(){
    this.bite=function(){
        dwn("Cat bite!");
    }
}
Cat.prototype=new Animal(); ///inherit Animal
function Dog(){
    this.bite=function(){
        dwn("Dog bite");
    }
}   
Dog.prototype=new Animal();  ///inherit Animal
function AnimalBite(animal){
    if(animal instanceof Animal) //这里是判断animal的原型是否指向Animal
    animal.bite();
}
var cat = new Cat();
var dog = new Dog();
AnimalBite(cat);
AnimalBite(dog);
//最终输出的结果如下:
/*
    Cat bite!
    Dog bite
*/

https://blog.csdn.net/qq_22896159/article/details/81779667

70.js事件机制(74.讲讲事件冒泡和事件捕获以及事件代理,事件委托 ?)

https://www.cnblogs.com/leftJS/p/10948138.html 

 js的事件机制:三个阶段:捕获,目标,冒泡

  • 事件冒泡:事件冒泡可以形象地比喻为把一颗石头投入水中,泡泡会一直从水底冒出水面。也就是说,事件会从最内层的元素开始发生,一直向上传播,直到document对象。
  • 事件捕获:网景提出另一种事件流名为事件捕获与事件冒泡相反,事件会从最外层开始发生,直到最具体的元素。

上面的例子在事件捕获的概念下发生click事件的顺序应该是document -> html -> body -> div -> p

W3C事件阶段(event phase):

https://www.cnblogs.com/wangzisheng/p/10025550.html

71.prototype (原型链)

当在一个对象上找一个属性的时候,要先在这个对象本身上找,所有对象上都有个_proto_属性 这个属性值是指向它构造函数的prototype的 如果对象本身没有这个属性 就会去找他的_proto_上找 (也就是构造函数的prototype)如果还没有就去 __proto__的__proto__上找 就这么一直找,这个搜索的过程,就叫做原型链

72.原型指针 

就是_proto_使指向它构造函数的原型 

垃圾回收机制 

js觉得这块东西或者变量不需要了 就会发现,然后清除(js自动执行)

怎么解决

  1. 标记清除法;
  2. 引用计数:使用完直接赋值为空

https://juejin.im/post/5b684f30f265da0f9f4e87cf

72.SEO是什么?Search Engine Optimization--搜索引擎优化

根据你收入的内容,浏览器检索出关键字

73.对象的深拷贝?ES6、ES5(高频)

  1. 浅拷贝:当原对象发生变化的时候,拷贝对象也跟着变化;
  2. 深拷贝: 另外申请了一块内存,内容和原对象一样,更改原对象,拷贝对象不会发生变化;

// 浅拷贝

var a = { count: 1, deep: { count: 2 } }
var b = Object.assign({}, a)
// 或者
var b = {...a}

// 实现浅拷贝的第二种方法

ES6中的Object.assign方法,Object.assign是ES6的新函数。Object.assign() 方法可以把任意多个的源对象自身的可枚举属性拷贝给目标对象,然后返回目标对象。但是 Object.assign() 进行的是浅拷贝,拷贝的是对象的属性的引用,而不是对象本身。

Object.assign(target, ...sources)
参数:

  • target:目标对象。
  • sources:任意多个源对象。
  • 返回值:目标对象会被返回。
var obj1 = {
    a: "hello",
    b: {
        a: "hello",
        b: 21}
};
 
var cloneObj1= Object.assign({}, obj1);
cloneObj1.a = "changed";
cloneObj1.b.a = "changed";
console.log(obj1.a);  //hello
console.log(obj.b.a); // "changed"

 // 深拷贝:一般需要借助递归实现,如果对象的值还是个对象,要进一步的深入拷贝,完全替换掉每一个复杂类型的引用。

// 手动复制--一个一个赋值
var obj1 = { a: 10, b: 20, c: 30 };
var obj2 = { a: obj1.a, b: obj1.b, c: obj1.c };
obj2.b = 100;
console.log(obj1);
// { a: 10, b: 20, c: 30 } <-- 沒被改到
console.log(obj2);
// { a: 10, b: 100, c: 30 }
var deepCopy = (obj) => {
    var ret = {}
    for (var key in obj) {
        var value = obj[key]
        ret[key] = typeof value === ‘object‘ ? deepCopy(value) : value
    }
    return ret
}

讲讲Map和Set?

  1. Map的key相比较普通对象来说更为灵活,普通对象的key只能以基础数据类型作为key值,并且所有传入的key值都会被转化成string类型,而Map的key可以是各种数据类型格式。
  2. Set可以讲讲它去重的特性。

 75.防抖节流

  1.  所谓防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。
  2. 所谓节流,就是指连续触发事件但是在 n 秒中只执行一次函数。

解决方法:加定时器,加loading

76.async/await

 async await 是用来解决异步的,async函数是Generator函数的语法糖

  •  async函数:声明异步函数,返回promise对象
  • await: 等待一个async函数的返回值
// async
async function test(){
    return 'test'
}
test()
// 控制台输出结果--返回的是一个promise对象
返回值为 Promise {<resolved>: "test"}
 
 
// await
function getSomething(){
    return 'something'
}
async function testAsync(){
    return Promise.resolve('hello async')
}
async function test(){
    const v1 = await getSomething();
    const v2 = await testAsync()
    console.log(v1,v2)
}
test()
// 控制台输入结果
something hello async
Promise {<fulfilled>: undefined}

https://segmentfault.com/a/1190000007535316 

JavaScript 中 this 是如何工作的

https://www.cnblogs.com/youngGao/p/8252998.html 

如何规避javascript多人开发函数重名问题?

尽量少的使用全局变量,尽可能使用局部变量 

请说出三种减低页面加载时间的方法.

  • 优化图片
  • 优化CSS 
  • 减少http请求

页面重构怎么操作?

  • 结构完整,可通过标准验证
  •  标签语义化,结构合理
  • 充分考虑到页面在站点中的“作用和重要性”,并对其进行有针对性的优化

js继承的6种方式 

https://www.cnblogs.com/humin/p/4556820.html 

new实现 

https://www.cnblogs.com/echolun/p/10903290.html 

暂时性死区

let 和 const 声明的变量不存在变量提升,其作用域都是块级作用域,凡是在声明变量之前使用变量就会报错,所以,在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。

if (true) {
  // 死区开始
  lzp = 'lut'; //  ReferenceError
  console.log(lzp); //  ReferenceError
 
  // 开始声明变量,死区结束
  let lzp; 
  console.log(lzp); // undefined
 
  lzp = 520;
  console.log(lzp); // 520
}

event

loop

JS有三类的错误:( JS 中的主要有哪几类错误)

  1. 加载时错误:加载web页面时出现的错误(如语法错误)称为加载时错误,它会动态生成错误。
  2. 运行时错误:由于滥用HTML语言中的命令而导致的错误。
  3. 逻辑错误:这些错误是由于对具有不同操作的函数执行了错误的逻辑而导致的

JS的作用域链是什么及其作用

一般情况下,变量取值到创建这个变量的函数的作用域中取值。但是如果在当前作用域中没有查到值,就会向上级作用域去查,直到查到全局作用域,这么一个查找过程形成的链条就叫做作用域链

JS中的作用域链主要用于解析变量的值。 如果没有这个,在不同的作用域内定义了许多变量,JS很难为变量选择某个值。

 JS中如何将页面重定向到另一个页面?

  1. 使用 location.href:window.location.href =“https://www.onlineinterviewquestions.com/”
  2. 使用 location.replace: window.location.replace(" https://www.onlineinterviewquestions.com/;");

列出JS中的一些设计模式:

  1. 创建模式:该模式抽象了对象实例化过程。
  2. 结构型模式:这些模式处理不同的类和对象以提供新功能。
  3. 行为模式:也称发布-订阅模式,定义了一个被观察者和多个观察者的、一对多的对象关系。
  4. 并行设计模式:这些模式处理多线程编程范例。
  5. 架构设计模式:这些模式用于处理架构设计。

如何在现有函数中添加新属性

 只需给现有函数赋值,就可以很容易地在现有函数中添加新属性。例如,现有一个对象person,通过下面的代码来为 person 添加新的属性:

person.country= “India”;

 JS中的宿主对象与原生对象有何不同?( 请指出 JavaScript 宿主对象 (host objects) 和原生对象 (native objects) 的区别?)

宿主对象:这些是运行环境提供的对象。这意味着它们在不同的环境下是不同的。例如,浏览器包含像windows这样的对象,但是Node.js环境提供像Node List这样的对象。 https://blog.csdn.net/foamflower/article/details/9165691

原生对象:这些是JS中的内置对象。它们也被称为全局对象,因为如果使用JS,内置对象不受是运行环境影响。

 js 获取原型的方法?

  •  p.proto
  • p.constructor.prototype
  • Object.getPrototypeOf(p)

从构造函数获得原型对象:  构造函数.prototype

从对象实例获得父级原型对象:1.对象实例._proto_       2.Object.getPrototypeOf(对象实例)

function Student(){
    this.name = "小马扎"; 
    this.age = 18;
}
var lilei = new Student();  // 创建对象实例
console.log(Student.prototype);  //Student{}
console.log(lilei.__proto__);  //Student{}
console.log(Object.getPrototypeOf(lilei));    //Student{}

 JS中为什么需要原型对象

JS使用构造函数创建对象时,每个实例对象的方法都存放在独立的内存中,不能共享;使用原型对象可以解决上面浪费内存空间

https://jingyan.baidu.com/article/597a0643a743aa712b52439b.html 

 JavaScript 原型,原型链?有什么特点? 

 每个对象都会在其内部初始化一个属性,就是prototype(原型)==(在JavaScript中,每个函数都有一个prototype属性,这个属性指向函数的原型对象。)

function Person(age) {
    this.age = age       
}
Person.prototype.name = 'kavin'
var person1 = new Person()
var person2 = new Person()
console.log(person1.name) //kavin
console.log(person2.name)  //kavin

https://www.cnblogs.com/loveyaxin/p/11151586.html

原型链:当我们去访问一个对象的属性时,如果这个对象内部不存在这个属性,那么他就会去prototype里面找这个属性,这个属性prototype就会有自己的prototype。
就这样一层一层的寻找,也就是我们平时所说的原型链的概念。

关系

instance.constructor.prototype=instance._proto_

JavaScript 对象是通过引用来传递的,我们创建的每个新对象实体中并没有一份属于自己的原型副本。当我们修改原型时,与
之相关的对象也会继承这一改变。 

什么是DOM和BOM

  • DOM  指的是文档对象模型,它指的是把文档当做一个对象来对待,这个对象主要定义了处理网页内容的方法和接口。
  • BOM  指的是浏览器对象模型,它指的是把浏览器当做一个对象来对待,这个对象主要定义了与浏览器进行交互的法和接口。

BOM
的核心是 window,而 window 对象具有双重角色,它既是通过 js 访问浏览器窗口的一个接口,又是一个 Global(全局)
对象。这意味着在网页中定义的任何对象,变量和函数,都作为全局对象的一个属性或者方法存在。window 对象含有 locati
on 对象、navigator 对象、screen 对象等子对象,并且 DOM 的最根本的对象 document 对象也是 BOM 的 window 对
象的子对象。 

 三种事件模型是什么? 

事件 是用户操作网页时发生的交互动作或者网页本身的一些操作,现代浏览器一共有三种事件模型。

  1. DOM0级模型: ,这种模型不会传播,所以没有事件流的概念,但是现在有的浏览器支持以冒泡的方式实现,它可以在网页中直接定义监听函数,也可以通过 js属性来指定监听函数。这种方式是所有浏览器都兼容的。

  2. IE 事件模型: 在该事件模型中,一次事件共有两个过程,事件处理阶段,和事件冒泡阶段。事件处理阶段会首先执行目标元素绑定的监听事件。然后是事件冒泡阶段,冒泡指的是事件从目标元素冒泡到 document,依次检查经过的节点是否绑定了事件监听函数,如果有则执行。这种模型通过 attachEvent 来添加监听函数,可以添加多个监听函数,会按顺序依次执行。

  3. DOM2 级事件模型: 在该事件模型中,一次事件共有三个过程,第一个过程是事件捕获阶段。捕获指的是事件从 document 一直向下传播到目标元素,依次检查经过的节点是否绑定了事件监听函数,如果有则执行。后面两个阶段和 IE 事件模型的两个阶段相同。这种事件模型,事件绑定的函数是 addEventListener,其中第三个参数可以指定事件是否在捕获阶段执行。

常用的正则表达式 

暂时先不了解 

JS

谈谈你对模块化开发的理解? 

  1.  我对模块的理解是,一个模块是实现一个特定功能的一组方法。在最开始的时候,js 只实现一些简单的功能,所以并没有模块的概念,但随着程序越来越复杂,代码的模块化开发变得越来越重要。
  2. 由于函数具有独立作用域的特点,最原始的写法是使用函数来作为模块,几个函数作为一个模块,但是这种方式容易造成全局变量的污染,并且模块间没有联系。
  3. 后面提出了对象写法,通过将函数作为一个对象的方法来实现,这样解决了直接使用函数作为模块的一些缺点,但是这种办法会暴露所有的所有的模块成员,外部代码可以修改内部属性的值。
  4. 现在最常用的是立即执行函数的写法,通过利用闭包来实现模块私有作用域的建立,同时不会对全局作用域造成污染。

 js 的几种模块规范? 

js 中现在比较成熟的有四种模块加载方案:

  • 第一种是 CommonJS 方案,它通过 require 来引入模块,通过 module.exports 定义模块的输出接口。这种模块加载方案是服务器端的解决方案,它是以同步的方式来引入模块的,因为在服务端文件都存储在本地磁盘,所以读取非常快,所以以同步的方式加载没有问题。但如果是在浏览器端,由于模块的加载是使用网络请求,因此使用异步加载的方式更加合适。

  • 第二种是 AMD 方案,这种方案采用异步加载的方式来加载模块,模块的加载不影响后面语句的执行,所有依赖这个模块的语句都定义在一个回调函数里,等到加载完成后再执行回调函数。require.js 实现了 AMD 规范。

  • 第三种是 CMD 方案,这种方案和 AMD 方案都是为了解决异步模块加载的问题,sea.js 实现了 CMD 规范。它和require.js的区别在于模块定义时对依赖的处理不同和对依赖模块的执行时机的处理不同。

  • 第四种方案是 ES6 提出的方案,使用 import 和 export 的形式来导入导出模块。这种方案和上面三种方案都不同。

requireJS的核心原理是什么? 

require.js 的核心原理是通过动态创建 script 脚本来异步引入模块,然后对每个脚本的 load 事件进行监听,如果每个脚本都加载完成了,再调用回调函数。 

谈谈JS的运行机制 

  •  所有同步任务都在主线程上执行,形成一个执行栈
  • 主线程之外还有一个“任务队列”。只要异步任务有了结果,就在“任务队列”之中放置一个事件
  • 一旦“执行栈”中所有同步任务都执行完成,系统就会读取“任务队列”,看看里面有哪些事件,哪些对应的异步任务,于是结束等待状态,进入执行栈,开始执行
  • 主线程不断重复上面第三步

 事件循环

主线程从“任务队列”中读取事件,这个过程是不断循环的 ,所以整个的这种运行机制就是事件循环 

60.宏任务和微任务 

  • 任务队列里面包括宏任务和微任务
  • 宏任务和微任务就是区分异步里面谁先执行
  • 先执行微任务再执行宏任务(有微则微 无微则宏)
  • 异步里先执行promise这种,最后执行settimeout这种,nexttick也是微任务
  • 同步肯定按顺序执行

对象是什么? 

arguments对象是函数中传递的参数值的集合。它是一个类似数组的对象,因为它有一个length属性,我们可以使用数组索引表示法arguments[1]来访问单个值,但它没有数组中的内置方法,如:forEach、reduce、filter和map。

我们可以使用Array.prototype.slice将arguments对象转换成一个数组。

function one() {
  return Array.prototype.slice.call(arguments);
}

 注意:箭头函数中没有arguments对象。

function one() {
  return arguments;
}
const two = function () {
  return arguments;
}
const three = function three() {
  return arguments;
}

const four = () => arguments;

four(); // Throws an error  - arguments is not defined

当我们调用函数four时,它会抛出一个ReferenceError: arguments is not defined error。使用rest语法,可以解决这个问题

const four = (...args) => args;

 这会自动将所有参数值放入数组中。

 ES6 模块与 CommonJS 模块、AMD、CMD 的差异。 

https://blog.csdn.net/u013681954/article/details/97299399 

es6==============================================

1.const let var 区别?

  • var声明变量存在变量提升,let和const不存在变量提升
  • let声明变量和const声明常量,两个都可以形成块级作用域
  • const声明之后必须赋值,否则会报错;一旦赋值就不能改变,为什么不能改变?因为是全局的
  • var是不受限于块级的,而let是受限于块级
  • ES5中是没有块级作用域的,并且var有变量提升,在let中,使用的变量一定要进行声明
  • const和let一样不会与window相映射、支持块级作用域、在声明的上面访问变量会报错
  • var会与window相映射(会挂一个属性),而let不与window相映射

2.变量提升:变量提升会优先声明

变量提升意思是 var声明变量时 先声明 再赋值

var a = 5;
function test3(){
        var a;
        cosnole.log(a)
}
test3();      ------------>undefined
  

var a = 5;
function test3(){
var a = 3;
console.log(a)
}
test3()    -------------->3 (变量提升)

函数提升:将整个代码块提升到他所在的作用域,最开始执行

var a = 1;
function foo() {
var a = function(){} ----->函数提升
a = 10;
console.log(a)------------10
return
}
foo()
console.log(a)--------------1

匿名函数不会被提升

3.什么是匿名函数

  • 语法:(function(){...}());
  • 前面的括号包含函数体,后面的括号就是给匿名函数传递参数并立即执行之
  • 匿名函数的作用是避免全局变量的污染以及函数名的冲突
  • 小括号的作用:小括号对返回的,就是一个匿名函数的Function 对象
(function(x,y){
alert(x+y);
return x+y;
}(3,4)); 

https://www.cnblogs.com/ClareZjy/p/6365891.html 

4.JS执行上下文

当代码运行时,会产生一个对应的执行环境,在这个环境中,所有变量会被事先提出来(变量提升),有的直接赋值,有的为默认值 undefined,代码从上往下开始执行,就叫做执行上下文。 (代码从上往下执行的过程就是执行上下文

运行环境:

  • 全局执行上下文,函数上下文与eval上下文(全局环境)
  • 全局上下文指:window对象(全局环境)
  • 函数上下文:指this自己(.函数环境)
  • eval上下文:一般不会用

5.js中this对象的指代

  • 全局环境中this指向window对象
  • 当前函数中,this指当前对象
  • 箭头函数没有this指向,this指向就箭头函数外部的函数,指向上下文

6.箭头函数,使用箭头函数应注意什么?

优点:

  • 语法简洁,函数定义不再使用关键字function(),而是用()=>来进行定义
  • 解决了this指向的问题,有一个确定的作用域
  • 如果只有一个形参,可以不打小括号
  • 如果只有一条执行语句,可以不打大括号
  • 只有一条执行语句,并且需要返回这条语句的结果,可以不用写return

注意:

  1. 用了箭头函数,this就不是指向window,而是父级(指向是可变的)
  2. 不能用作构造函数这就是说不能够使用new命令,否则会抛出一个错误
  3. 不能够使用arguments对象
  4. 不可以使用yield命令,因此箭头函数不能用作 Generator 函数

举例子: 

箭头函数的写法:
// ES5
var x = function(x, y) {
     return x * y;
}
 
// ES6
const x = (x, y) => x * y;
  • 箭头函数是匿名函数的一种简写方式
  • ()内是参数,一个参数的时候可以省略
  • =>后面是返回值,省略了return
  • 词法作用域,不会绑定this;箭头函数会默认绑定外层的this的值,所以箭头函数中this的值和外层this的值是一样的
  • 如果函数部分只是一个语句,则可以省略return关键字和大括号{}
以下两者等价
const x = (x, y) => x * y;
 
const x = (x, y) => { return x * y };

7.模板字符串

模版字符串,用`(反引号)标识,用${}将变量括起来。

var name="zzw";
`${name},no matter what you do,I trust you.`

https://www.cnblogs.com/xiaowie/p/11601599.html 

8. ... 展开运算符

可以将数组或对象里面的值展开;还可以将多个值收集为一个变量

数组合并的时候用

// 数组合并
var array1 = [1, 2, 3,4];
var array2 = [4, 5, 6];
var array3 = [...array1, ...array2, 7, 8]; //[1,2,3,4,4,5,6,7,8]
array1.push(...array2 )// 当然也可以使用concat等数组合并方法,但是扩展运算符提供了一种新的方式

结构赋值 

所谓的解构赋值其实就是分解出一个对象的解构,分成两个步骤:

  1. 变量的声明
  2. 变量的赋值 
let node = {
    type: "Identifier",
    name: "foo"
};
let { type, name } = node;
console.log(type); // "Identifier"
console.log(name); // "foo"

9.promise(异步)--解决异步问题

promise是一个对象,可以获取异步操作的消息,promise提供统一的API,各种异步操作都能处理

2个特点:

  • 对象的状态不受外界影响 (3种状态)
    • Pending状态(进行中)
    • Fulfilled状态(已成功)
    • Rejected状态(已失败)
  • 一旦状态改变就不会再变 (两种状态改变:成功或失败)
    • Pending -> Fulfilled
    • Pending -> Rejected
var promise = new Promise(function(resolve, reject){
    // ... some code
    if (/* 异步操作成功 */) {
        resolve(value);
    } else {
        reject(error);
    }
})

 Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolvereject。它们是两个函数,由JavaScript引擎提供,不用自己部署。
 resolve作用是将Promise对象状态由“未完成”变为“成功”,也就是Pending -> Fulfilled,在异步操作成功时调用,并将异步操作的结果作为参数传递出去;而reject函数则是将Promise对象状态由“未完成”变为“失败”,也就是Pending -> Rejected,在异步操作失败时调用,并将异步操作的结果作为参数传递出去。

then:

 Promise实例生成后,可用then方法分别指定两种状态回调参数。then 方法可以接受两个回调函数作为参数:

  1. Promise对象状态改为Resolved时调用 (必选)
  2. Promise对象状态改为Rejected时调用 (可选)
 routeInfo (type = 'edit') {
    return new Promise((resolve, reject) => {
      this.listData(type).then(result => {
        return new Promise((resolve) => {
          let res = result.list[0]
          if (result.list.length !== 1) {
            console.warn('待办结果不唯一')
          }
          resolve(res)
        })
      }).then(res => {
        this.dataValidator(res, type).then(res => {
          resolve({
            name: this.info[this.typeCode][type].routerName,
            query: this.info[this.typeCode][type].query(res),
            params: this.info[this.typeCode][type].params && this.info[this.typeCode][type].params(res)
          })
        }).catch(e => {
          reject(e)
        })
      }).catch(e => {
        reject(e)
      })
    })
  }

all:多个请求一起发出并根据请求顺序获取和使用数据的场景

    getData () {
      Promise.all([
        this.getCreditData(),
        this.getProjectData()
      ]).then(result => {
      }).finally(() => {
        this.loading.detail = false
      })
    },

 catch:reject状态时才会进入,捕获错误信息

let p2 = new Promise((resolve, reject) => {
        reject('123');
}).catch(e => e);

finally() :成功失败都进finally

finally()方法用于指定不管Promise对象最后状态如何,都会执行的操作。

Promise.then(result => {}).catch(error => {}).finally(() =>{})

10.Symbol(第七种基本数据类型)

Symbol是一种基本类型。Symbol 通过调用symbol函数产生,它接收一个可选的名字参数,该函数返回的symbol是唯一的

好处:用来定义对象的唯一属性名(类似于id一样是唯一标识)

缺点:

Symbol类型是不能通过Object.keys()或者for...in来枚举,因为不包含在对象自身的属性名集合(property name)中

因此:使用JSON.stringify()将对象转成JSON字符串的时候,Symbol这个属性也会排除在外

(1)为什么引入Symbol?

之前的对象属性名是字符串,容易造成属性名冲突

(2)typeof运算符用于Symbol类型值,返回symbol

let name = Symbol()
console.log(typeof name)   // Symbol

(3)Symbol的值和谁都不相等,是独一无二的值.

 let symbol1 = Symbol()
 let symbol2 = Symbol()
 console.log(symbol1 === symbol2)  // false
 console.log(symbol1 == symbol2)   // false
 symbol1和symbol2相等吗?

不相等.因为Symbol类型的值是独一无二的值.

(4).为什么Symbol不能用new关键字?

let obj = new Symbol()     // TypeError

symbol值不是对象,所以不能添加属性

(5)console.log(Symbol(‘Alice’) + “bruce”)   // TypeError,为什么错误?

Symbol值不能与其他类型的值进行运算

(6)如何读取Symbol的属性值?

 let name = Symbol()
 let obj = {}
 obj[name] = “Alice”
 cosnole.log(obj[name])

Symbol值定义属性时,必须放在方括号内,不能用点运算符。

(7)Symbol的值显示的转成字符串或者布尔值,但是不能转成数值.

(8)获取对象属性的两种方法

  Object.getOwnPropertySymbols()   和  Object.getOwnPropertyNames() 

11.set数据结构

理解:
Set本身是一个构造函数,用来生成Set数据结构。类似于数组,但是成员的值是唯一分,不重复的。

用法:

1.//  数组去重
  [...new Set([1,2,3,3])]  // [1,2,3]
//  字符串去重
  [...new Set([‘zyy’])].join(‘’)   // ‘zy’

注意

向Set加入值的时候,不会发生类型转换,所以5和’5’是两个不同的值。Set内部判断两个值是否不同,使用的算法叫做“same-value-zero equality”,它类似于精确相等运算符(===)

let set = new Set()
set.add(NaN)
set.add(NaN)
console.log(set)   // Set{NaN}
// 也就是说NaN是相等的
let set = new Set()
set.add({})
set.add({})
console.log(set.size)		// 2
// 也就是说,上面的2个空对象是不相等的

 什么是`Set`对象,它是如何工作的? 

Set 对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用。

https://www.mybj123.com/6712.html 

什么是Proxy? (代理--不会)

Proxy 用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种“元编程”,即对编程语言进行编程。

Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。Proxy 这个词的原意是代理,用在这里表示由它来“代理”某些操作,可以译为“代理器”。

=================================================================================(下面不是高频的) 

11.Map 

理解:

类似于对象,也是键值对的集合,但”键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Object结构提供了”字符串-值” 的对应,Map结构提供了”值-值”的对应,是一种更完善Hash结构实现。

用法:

const map = new Map({
[‘name’: ‘张三’],
['title', 'Author']
})
map.size  // 2
map.has(‘name’)  // true
map.get(‘name’)  // ‘张三’

经典题:
set特点:是构造函数    类似于数组,但是里面的值是唯一的
1.实现数组去重和set的交集,并集,差集

// 数组去重
console.log([...new Set([1,2,2])])    // [1,2]
console.log(Array.from(new Set([1,2,2])))   //[1,2]

let set1Arr = new Set([1,2,3])
let set2Arr = new Set([2,3,4])
// 交集
let jiao = new Set([...set1Arr].filter(x => set2Arr.has(x)))
console.log(“jiao”,jiao)  // set(2){2,3}
// 并集
console.log( new Set([...set1Arr,...set2Arr]))  // Set(4){1,2,3,4}
// 差集
let cha = new Set([...set1Arr].filter(x => !set2Arr.has(x)))
console.log(“cha”,cha)   // 	Set(1) {1}

给定一个整数无序数组和变量 sum,如果存在数组中任意两项和使等于 sum 的值,则返回true。否则, 返回false。例如,数组[3, 5, 1, 4]和 sum = 9,函数应该返回true,因为4 + 5 = 9。

//常规版本
const findSum = (arr, val) => {
   let searchValues = new Set();
   searchValues.add(val - arr[0]);
   for (let i = 1, length = arr.length; i < length; i++) {
        let searchVal = val - arr[i];
        if (searchValues.has(arr[i])) {
          return true;
        } else {
        searchValues.add(searchVal);
         }
      };
     return false;
};


//简洁的版本:
const findSum = (arr, sum) =>
arr.some((set => n => set.has(n) || !set.add(sum - n))(new Set));

let findS = findSum([3, 5, 1, 4], 9)
console.log(findS) //true

Set上的forEach()方法

forEach()方法还会被传递一个回调函数,该回调函数接受3个参数

  1. Set中下个位置
  2. 与第一个参数相同的值
  3. 目标Set本身

由于Set没有键,为了使forEach方法与数组和map的forEach方法一致:将Set中的每一项同时认定为键与值。

let set = new Set([1, 2]);
 set.forEach(function(value, key, ownerSet) { 
console.log(`${key} ${value}`) 
console.log(ownerSet === set); 
})
1 1
True
2 2
True

8.解构赋值

ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值

类模板字符串的功能

let name = 'web';
let age = 10;
let str = '你好,${name} 已经 ${age}岁了'
str = str.replace(/\$\{([^}]*)\}/g,function(){
     return eval(arguments[1]);
})
console.log(str);//你好,web 已经 10岁了

https://blog.csdn.net/qq_30904985/article/details/81300883 

9.import、export导入导出

ES6标准中,Js原生支持模块(module)。将JS代码分割成不同功能的小块进行模块化,将不同功能的代码分别写在不同文件中,各模块只需导出公共接口部分,然后通过模块的导入的方式可以在其他地方使用

 9.修饰器 @

decorator是一个函数,用来修改类甚至于是方法的行为。修饰器本质就是编译时执行的函数

10.class 类的继承

ES6中不再像ES5一样使用原型链实现继承,而是引入Class这个概念

23.Promise 中reject 和 catch 处理上有什么区别

reject 是用来抛出异常,catch 是用来处理异常

reject 是 Promise 的方法,而 catch 是 Promise 实例的方法

reject后的东西,一定会进入then中的第二个回调,如果then中没有写第二个回调,则进入catch

网络异常(比如断网),会直接进入catch而不会进入then的第二个回调

14.Proxy代理

使用代理(Proxy)监听对象的操作,然后可以做一些相应事情

15.ECMAScript 6 怎么写 class ,为何会出现 class?

ES6的class可以看作是一个语法糖,它的绝大部分功能ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法

//定义类
class Point { 
  constructor(x,y) { 
      //构造方法
       this.x = x; //this关键字代表实例对象
       this.y = y; 
  } toString() {
       return '(' + this.x + ',' + this.y + ')'; 
  }
}

21.字符串的截取两个方法(subString subStr)的区别?

  1. stringObject.substr(start,length):在字符串中抽取从 start 下标开始的指定数目的字符
  2. stringObject.substring(start,stop): 用于提取字符串中介于两个指定下标之间的字符

19.下面的输出结果是多少

const promise = new Promise((resolve, reject) => {
    console.log(1);
    resolve();
    console.log(2);
})

promise.then(() => {
    console.log(3);
})

console.log(4);

1 2 4 3

Promise 新建后立即执行,所以会先输出 1,2,而 Promise.then() 内部的代码在 当次 事件循环的 结尾 立刻执行 ,所以会继续输出4,最后输出3

20.使用结构赋值,实现两个变量的值的交换

let a = 1;let b = 2;
[a,b] = [b,a];

21.设计一个对象,键名的类型至少包含一个symbol类型,并且实现遍历所有key

 let name = Symbol('name');
 let product = {
    [name]:"洗衣机",    
    "price":799
  };
  Reflect.ownKeys(product);

22.下面Set结构,打印出的size值是多少

let s = new Set();
s.add([1]);
s.add([1]);console.log(s.size);

答案:2

两个数组[1]并不是同一个值,它们分别定义的数组,在内存中分别对应着不同的存储地址,因此并不是相同的值

都能存储到Set结构中,所以size为2

24.使用class 手写一个promise

//创建一个Promise的类
  class Promise{
    constructor(executer){//构造函数constructor里面是个执行器
      this.status = 'pending';//默认的状态 pending
      this.value = undefined//成功的值默认undefined
      this.reason = undefined//失败的值默认undefined
      //状态只有在pending时候才能改变
      let resolveFn = value =>{
        //判断只有等待时才能resolve成功
        if(this.status == pending){
          this.status = 'resolve';
          this.value = value;
        }
      }
      //判断只有等待时才能reject失败
      let rejectFn = reason =>{
        if(this.status == pending){
          this.status = 'reject';
          this.reason = reason;
        }
      }    
      try{
        //把resolve和reject两个函数传给执行器executer
        executer(resolve,reject);
      }catch(e){
        reject(e);//失败的话进catch
      }
    }
    then(onFufilled,onReject){
      //如果状态成功调用onFufilled
      if(this.status = 'resolve'){
        onFufilled(this.value);
      }
      //如果状态失败调用onReject
      if(this.status = 'reject'){
        onReject(this.reason);
      }
    }
  }

26.将下面for循环改成for of形式

let arr = [11,22,33,44,55];
let sum = 0;
for(let i=0;i<arr.length;i++){
    sum += arr[i];
}

答案:

let arr = [11,22,33,44,55];
let sum = 0;
for(value of arr){
    sum += value;
}

28.forEach、for in、for of三者区别

forEach更多的用来遍历数组
for in 一般常用来遍历对象或json
for of数组对象都可以遍历,遍历对象需要通过和Object.keys()
for in循环出的是key,for of循环出的是value

29.说一下es6的导入导出模块

// 只导入一个
import {sum} from "./example.js"
// 导入多个
import {sum,multiply,time} from "./exportExample.js"
// 导入一整个模块
import * as example from "./exportExample.js"

导出通过export关键字

//可以将export放在任何变量,函数或类声明的前面
export var firstName = 'Michael';
export var lastName = 'Jackson';
export var year = 1958;

//也可以使用大括号指定所要输出的一组变量
var firstName = 'Michael';
var lastName = 'Jackson';
var year = 1958;
export {firstName, lastName, year};

//使用export default时,对应的import语句不需要使用大括号
let bosh = function crs(){}
export default bosh;
import crc from 'crc';

//不使用export default时,对应的import语句需要使用大括号
let bosh = function crs(){}
export bosh;
import {crc} from 'crc';

13.堆栈内存(没看)

当浏览器加载页面时,会形成两个虚拟的内存;一个栈内存,堆内存;

栈内存:

  1. 提供代码的运行环境;
  2. 存储基本数据类型;

堆内存: 存储引用数据类型

28.函数的递归

递归: 针对的是函数; 是JS中一种重要的思想; 
函数: 分为定义和执行 
函数递归: 在函数体内部,调用函数自己本身,让其执行;这就是递归;

function sum(num) {
if(num === 0){
return num;
}
if(num%3===0){
return num + sum(num-1);
}
if(num%3!==0){
return sum(num-1);
}
// return sum(99)
// return 99 + sum(98)
// return 99 + sum(97)
// return 99 + sum(96)
// return 99 + 96 + sum(95)....
// return 99 + 96 +... + 3 + sum(2)
// return 99 + 96 +... + 3 + sum(1)
// return 99 + 96 +... + 3 + 0
}
console.log(sum(100));
console.log(sum(200));

29.求1-100之间是3倍数的和(% : 取模;取余数)

var total = 0;
for(var i=0;i<100;i++){
if(i%3===0){
total += i;
}
}

30.数组的插入排序

var ary = [12,88,67,98,56,35,45,26,1];
//5 6 7 8 10
//得到的新数组是排好序
//插入排序原理:去原有数组中去取每一项,然后和新数组中的成员进行比较,从新数组后面开始,一一向前比较,比新数组项小,继续和前一项比较,直到当前项比数组中一项值大时,把它放到这一项的后面;
var newAry = [];
newAry.push(ary[0]);
for(var i=1;i<ary.length;i++){
var cur = ary[i];
for(var j=newAry.length-1;j>=0;j--){
if(cur<newAry[j]){// 如果数组中拿到的这一项比新数组中j的这一项小;那么继续j--;和上一个成员进行比较;
if(j===0){
newAry.unshift(cur);
break;// 只会中止当前的小循环
}
}else{
// cur<newAry[j]的情况,把当前项放到新数组这一项的后面;
newAry.splice(j+1,0,cur);
break;
}
}
}
// 从前向后
console.log(newAry);
var ary = [12,88,67,98,56,35,45,26,1];
var mAry = [12,67,88];
mAry.push(ary[0]);
for(var i=1;i<ary.length;i++){
var cur = ary[i];
for(var j = mAry.length-1;j>=0;j--){
if(cur<mAry[j]){
if(j===0){
mAry.unshift(cur);
break;
}
}else{
mAry.splice(j+1,0,cur);
break;
}
}
}

30.数组的冒泡排序

var ary = [12,32,56,67,88,99,101];
// 1. sort
/*ary.sort(function (a,b) {
return a-b;// 从小到大
});*/
// 实现从小到大
// 让相邻两项进行比较,如果前面一项比后面一项大,那么让这两项互换位置;如果前比后面一项小,那么不换位置;每循环一整轮,把数组的最大值放到数组的最后面;有多少项,就执行多少次这样的循环;
for(var j = 0;j<ary.length;j++){
// 当外面的循环循环一次;
var flag = true;// 标识的作用
for(var i=0;i<ary.length-1-j;i++){
// 里面整个循环完一次,实现将最大值放到最后;
if(ary[i]>ary[i+1]){//前面一项比后面大
// 借助第三方变量
//如果能进来,说明数组没有排好顺序;如果进不来,说明数组已经是排好的
var temp = ary[i];
ary[i] = ary[i+1];
ary[i+1] = temp;
flag = false;
}
}
if(flag){
break;
}
}
console.log(ary);

31.数组的快速排序(快速排序快速排序的原理: 首先取原有数组中的中间项;接下来循环原有的数组每一项,和中间项进行比较,如果比中间项的小的放在左边的数组中,比中间项大的放在右边的数组中;然后再对左边和右边数组进行刚才的操作;最后把所有的小数组和中间项串在一起就是排好的数组;)

var ary = [12,8,89,78,76,56,25,35];
function quickSort(ary) {
console.log(ary);
// 当数组的长度小于等于1;直接return当前的数组;
if(ary.length<=1){
return ary;
}
//获取
var middleIndex = Math.floor(ary.length/2);
//删除数组中中间项;并且获取中间项的值
var middleVal = ary.splice(middleIndex,1)[0];
console.log(middleVal);
var left = [];
var right = [];
for(var i=0;i<ary.length;i++){
var cur = ary[i];
//比中间项的小的放中间项的左边的数组,比中间项大的放中间项的右边的数组
if(cur<middleVal){
left.push(cur);
}else{
right.push(cur);
}
}
//对中间左右两边的数组进行重新这样的操作
return quickSort(left).concat(middleVal,quickSort(right))
}
var newAry = quickSort(ary);
console.log(newAry);

32.随机验证码

var code = document.getElementById("code");
function getCode() {
// 准备一个62个字符串;
// 产生随机数;随机数可以作为字符的索引;
// 随机索引范围【0-61】
var str = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
// 随机数;
var i =0;
var newStr = "";
while(i<4){
var num = Math.round(Math.random()*(61-0)+0);
newStr+=str[num];
i++;
}
code.innerHTML = newStr;
}
getCode();
// 把函数的空间地址赋值给code的onclick属性;
code.onclick = getCode;

43.看下列代码会有什么样的输出?

var foo = "11"+2-"1";  
console.log(foo);//112-1=111
console.log(typeof foo);//”number”

考点:
1、数字和字符串都可以用加法运算符,数字和字符串相加,结果就是一个字符串
2、但是减法运算符只能用于两个数字之间,想要执行减法运算,必须把两边数字都变成数字类型的
答案:”111”、”number”

45.已知数组var stringArray = [“This”, “is”, “Baidu”, “Campus”],alert出”This is Baidu Campus”。

考点:数组的join方法的使用,将一个数组通过指定字符分隔组成一个想要的字符串
答案:alert(stringArray.join(“ ”))

46.已知有字符串foo=”get-element-by-id”,写一个function将其转化成驼峰表示法”getElementById”。

    function combo(msg){
    var arr=msg.split("-");//[get,element,by,id]
    for(var i=1;i<arr.length;i++){
        arr[i]=arr[i].[0].toUpperCase()+arr[i].substring(1);//Element
    }
    msg=arr.join("");//msg=” getElementById”
    return msg;
}

47.var numberArray = [3,6,2,4,1,5];

1)实现对该数组的倒排,输出[5,1,4,2,6,3]

function reverseArray(arr){
    var result=[];
    //方法1:
    /*for (var i = arr.length - 1; i >= 0; i--) {
        result.push(arr[i]);
    }*/
    //方法2:
    for (var i = 0, len = arr.length; i < len; i++) {
        result.unshift(arr[i]);
    }
    return result;
}

2)实现对该数组的降序排列,输出[6,5,4,3,2,1]

function sortDesc(arr) {
    for (var i = 0, len = arr.length; i < len; i++) {
        for (var j = i + 1, len2 = arr.length; j < len2; j++) {
            //>就是降序 <就是升序
            if (arr[j] > arr[i]) {
                var temp = arr[j];
                arr[j] = arr[i];
                arr[i] = temp;
            }
        }
    }
    return arr;
}

51.用js实现随机选取10–100之间的10个数字,存入一个数组,并排序。

var iArray = []; 
function getRandom(istart, iend){
        var iChoice = iend - istart +1;
        return Math.floor(Math.random() * iChoice+ istart);
}
Math.random()就是获取0-1之间的随机数(永远获取不到1)
for(var i=0; i<10; i++){
var result= getRandom(10,100);
        iArray.push(result);
}
iArray.sort();

52.把两个数组合并,并删除第二个元素。

考点:1、数组的concat、splice用法
splice() 方法删除数组的元素,或者向数组中添加元素,然后返回被删除的项目。
参数1:从何处开始删除数组的元素(使用负数则从数组的末尾开始)
参数2:要删除的元素个数(如果是0,就代表不删除)
参数3,4,5。。。:要添加的元素

var array1 = ['a','b','c'];

var bArray = [‘d’,’e’,’f’];
var cArray = array1.concat(bArray);
cArray.splice(1,1);

53.写一个function,清除字符串前后的空格。(兼容所有浏览器)

使用自带接口trim(),考虑兼容性(IE9以下浏览器不支持):
考点:1、原型扩展 2、正则表达式 3、字符串的replace方法

if(typeof String.prototype.trim !=”function”){
String.prototype.trim=function(){
return this.replace(/^\s+|\s+$/g,”“);
}
}
var str=” hello “;

54.Javascript中, 以下哪条语句一定会产生运行错误? 答案( BC )             ??????????????

A、var _变量=NaN;      // 
B、var 0bj = [];             // Invalid or unexpected token
C、var obj = //;           
D、var obj = {};
//正确答案:BC

56.Javascript创建对象的几种方式?

构造函数方式,原型模式,混合构造函数原型模式,工厂方式,动态原型方式

混合构造函数+原型模式:

function Robot(name){
    this.name=name;
}
Robot.prototype.say=function(){
    alert("大家好,我叫"+this.name);
};
var alphaGo=new Robot("阿尔法狗");
alphaGo.say();

工厂方式:

function create(name,age){
    var o={};
    o.name=name;
    o.age=age;
    return o;
}
var p1=create("张三",20);

动态原型方式:

function Person(name,work){
    this.name=name;
    if(work){
        Person.prototype.doWork=function(){
            alert("我正在从事"+work+"的工作");
        }
    }
}
var p1=new Person("姚明");
var p2=new Person("喵喵","程序猿鼓励师");

59.documen.write和 innerHTML 的区别?

  • document.write 指定位置输出
  • dom.innerHTML 可以重绘指定元素的内容
  • document.write和innerHTML的区别

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

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

62.将数字 12345678 转化成 RMB形式 如: 12,345,678

//思路:先将数字转为字符, str= str + ” ;
//利用反转函数,每三位字符加一个 ‘,’最后一位不加; re()是自定义的反转函数,最后再反转回去!

for(var i = 1; i <= re(str).length; i++){
    tmp += re(str)[i - 1];
    if(i % 3 == 0 && i != re(str).length){
        tmp += ',';
    }
}

64.什么是三元表达式 (Ternary expression)?“三元 (Ternary)” 表示什么意思?

一个运算符如果有一个操作数,为一元运算符,两个为二元,三个为三元运算符,三元表达式则为一个三元运算表达式!

71.如果某一个接口很缓慢,用户离开这个页面该怎么处理?

84.内建对象:Object,Array,自定义对象

var Obj = new Object()
// 添加属性
obj.name = "小明"
// 添加方法
obj.sleep = function(){
console.log(this.name + '在')
}

内建对象可以通过几种方式创建

  1. new关键字创建对象
  2. 通过字面量创建对象   var fun = new fun()
  3. 构造函数对象
  4. 用中括号法访问属性

87.什么是数组?什么是对象

数组:用于在变量中存储多个值,以下角标为标识

方法:

cocat()   .............................合并数组

pop....................................删除最后一位

push.................................添加最后以为

shift.................................. 删除第一位

unshift.............................增加第一位

reverse............................反转

slice...................................截取指定位置数组

sort.................................数组排序

splice...............................删除指定位置

toString.............................转成字符串并返回

indexOf............................数组的索引

map()同forEach

forEach   遍历数组,没有返回值

forEach(value,index,self)

value:遍历数组的数据

index:对应索引

self: 数组自身

map:同forEach功能

map的回调函数会执行结果,然后map将所有回调函数的返回值组成一个新数组返回

forEach与map区别

相同点:

1.都是循环遍历数组中的每一项

2.都有3个参数,item(当前每一项),index(索引值),arr(原数组)

不同点:

forEach:遍历数组,无返回值

map遍历数组,有返回值

93.js有几种弹出窗

alert.confirm,prompt

  • alert:警告窗
  • confirm:确认窗口
  • prompt:信息输入窗口

VUE面试题

-------------------

vue中更新版本/升级添加版本号/项目升级/打包部署/等

1.对MVVM的理解

  • M:model层,在model层对数据进行操作和修改数据
  • V:View(视图层)
  • VM:ViewModel监听模型数据的改变和控制视图行为。相当于模型层和视图层的一个桥梁,起连接作用。

在MVVM模式下,View和Modal没有直接的联系,而是通过ViewModal进行交互,Modal和ViewModal之间交互是双向的,因此View数据的变化会同步到Modal上,Modal数据的变化也会立即反应到View上。

ViewModal通过数据双向绑定把View和Modal层连接起来,而View和Modal之间的工作同步是完全自动的,无需别人干涉,因此开发者只关注业务逻辑,不需要动手操作DOM,不需要关注状态的同步问题,复杂的数据状态完全由MVVM管理

2.生命周期:Vue实例从创建到销毁的过程。从开始创建,初始化数据,编译模板,挂载DOM->渲染,更新->渲染,销毁等一系列过程。

  • beforeCreate(创建前):只是单纯的创建$el和data,数据观测和初始化时间还未开始(自己理解:只是单纯的创建$el和data
  • created(创建后):完成数据观测,属性和方法的运算,初始化事件(data),但是$el属性还没有显示出来(自己理解:data初始化完成,$el仍只是创建中
  • beforeMounte(挂载前):在挂载开始之前被调用,相关的render函数首次被调用。实例已完成以下的配置:编译模板,把data里面的数据和模板生成html。注意此时还没有挂载html到页面上。(自己理解:vue实例的$el和data都初始化完成,但data还是挂载之前虚拟的DOM节点,data尚未替换,此时还没有挂载html在页面上
  • mounted(载入后):在el被创建的vm.$el替换,并挂载到实例上去之后调用。实例已完成以下的配置。用上面编译好的html内容替换el属性指向DOM对象。完成模板的html渲染到html页面上。此过程是ajax交互过程(自己理解:用真实数据替换虚拟DOM
  • beforeUpdate(更新前): 重新渲染之前触发(自己理解:data数据已经发生改变,但是未渲染
  • updated(更新后):数据已经更改完成,dom也重新render完成,更改数据会陷入死循环(自己理解:data数据已经发生改变,并且旧数据代替新数据
  • beforeDestory(销毁前):在实例销毁之前调用。实例仍然完全可用
  • destoryed(销毁后):在实例销毁之后调用。调用后,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。

(1).生命周期的作用?

生命周期有很多钩子函数,通过钩子函数让我们在控制整个Vue实例的过程时更容易形成好的逻辑。

(2).生命周期总共有几个阶段?

8个,创建前/后;载入前/后;更新前/后;销毁前/后

(3).第一次页面加载会出发那几个钩子?

beforeCreate, created, beforeMount, mounted 

(4).DOM渲染在哪个周期已经完成?

mounted

(5)简单描述每个周期具体适合那些场景?

  • beforeCreate:可以在这个上加loading事件,在加载实例时触发
  • created:初始化完成时的事件写在这里,如在这结束loading事件,异步请求的调用 
  • mounted:挂载元素,获取到DOM节点  
  • beforeDestory:可以做停止确认框事件
  • nexTick:改变dom元素,nexTick()方法延时调用函数事件来渲染视图

[更改数据后当你想立即使用js操作新的视图的时候需要使用它]

注意:2.1.0新增:如果没有提供回调且在支持Promise环境中,则返回一个Promise.请注意Vue不自带Promise的polyfill,如果你的目标浏览器不原生支持Promise,你需要自己提供,请查阅-------Vue官网--异步更新队列

https://cn.vuejs.org/v2/guide/reactivity.html#%E5%BC%82%E6%AD%A5%E6%9B%B4%E6%96%B0%E9%98%9F%E5%88%97

    changeTxt:function(){
      let that=this;
      that.testMsg="修改后的文本值";  //修改dom结构
       
      that.$nextTick(function(){  //使用vue.$nextTick()方法可以dom数据更新后延迟执行
        let domTxt=document.getElementById('h').innerText; 
        console.log(domTxt);  //输出可以看到vue数据修改后并没有DOM没有立即更新,
        if(domTxt==="原始值"){
          console.log("文本data被修改后dom内容没立即更新");
        }else {
          console.log("文本data被修改后dom内容被马上更新了");
        }
      });
    },

(6)created和mounted的区别

  • created:在模板渲染成html前调用,即通常初始化某些属性值,然后再渲染成视图。
  • mounted:在模板渲染成html后调用,通常是初始化页面完成后,再对html的dom节点进行一些需要的操作。

 https://www.jianshu.com/p/a7550c0e164f

3.VUE双向绑定原理

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

具体步骤:

第一步:需要observe的数据对象进行递归遍历,包括子属性对象的属性,都加上setter和getter

这样的话,给这个对象的某个值赋值,就会触发setter,那么就能监听到了数据的变化

第二步:compile解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图

第三步:Watcher订阅者是Observer和Compile之间通信的桥梁,主要做的事情是:

1.在自身实例化时往属性订阅器(dep)里面添加自己

2.自身必须有一个update()方法

3.待属性变动dep.motice()通知时,能调用自身的update()方法,并触发Compile中绑定的回调,则功成身退。

第四步:MVVM作为数据绑定的入口,整合Observer、Compile和Watcher三者,通过Observer来监听自己的model数据变化,通过Compile来解析编译模板指令,最终利用Watcher搭起Observer和Compile之间的通信桥梁,达到数据变化 -> 视图更新;视图交互变化(input) -> 数据model变更的双向绑定效果。

4.Vue组件间的参数传递;(vue组件传值)

一:父子关系组件

1.父向子传值

父组件向子组件传值用props属性。首先,在子组件里定义一个props值用来接收父组件数据;然后调用子组件并v-bind绑定这个props值 = 父组件的data值。

父组件代码:

<template>
  <div class="home">
    <HelloWorld :newMsg="msg" /> 
    //绑定子组件newMsg(props值) = 父组件msg(data值)
  </div>
</template>

<script>
import HelloWorld from "@/components/HelloWorld.vue";
export default {
  name: "Home",
  data(){
    return{msg:'Welcome to Vue.js'} //父组件数据msg
  },
  components: {HelloWorld}
};
</script>

子组件代码:

<template>
  <div>
    <h1>{
   
   { newMsg }}</h1>  //直接调用newMsg,显示“Welcome to Vue.js”
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  props: {newMsg: String}  //为子组件定义newMsg(props值)接收父组件msg
  //或者props:['newMsg']
};
</script>

2.子组件向父组件传值

子组件向父组件传值有两种方式:

(1):利用$emit()方法。 首先在子组件中用$emit()向上传递一个自定义事件并附带想要传递的数据;然后在父组件v-on监听这个自定义事件并自动接收到数据;最后在响应该事件的方法中进行数据操作。

子组件代码:

<script>
export default {
  name: "HelloWorld",
  data() {
    return {msg:"Welcome to Vue"} //data值,即将向上传递的值
  },
  created(){
    this.$emit('change',this.msg) //向上传递自定义事件change和data值。这里我调用created生命周期函数触发$emit()
  }
};
</script>

 父组件代码:

<template>
  <div class="home">
    <HelloWorld @change="handle" /> //监听到子组件传递来的事件并响应handle方法
    <span>{
   
   {newMsg}}</span>  //直接调用newMsg,显示“Welcome to Vue”
  </div>
</template>

<script>
import HelloWorld from "@/components/HelloWorld.vue";
export default {
  name: "Home",
  data() {
    return {newMsg:""}
  },
  methods:{
    handle(msg){           //定义handle方法,将自动接收到的msg值给了自己的newMsg
      this.newMsg = msg
    }
  },
  components: {HelloWorld}
};
</script>

(2)利用ref属性。ref是vue的内部属性,类似于id,class标识。首先在子组件上定义ref值(例:ref="son");然后在父组件中用this.\$refs.son即可获取到son这个ref的组件,进行操作。

子组件代码:

<script>
export default {
  name: "HelloWorld",
  data() {
    return {msg:"Welcome to Vue"}  //即将向父传递的data值
  }
};
</script>

 父组件代码:

<template>
  <div class="home">
    <HelloWorld ref="son" />  //在子组件上定义一个ref 名为"son"
  </div>
</template>

<script>
import HelloWorld from "@/components/HelloWorld.vue";
export default {
  name: "Home",
  mounted(){
    console.log(this.$refs.son.msg)  //获取到ref名为"son"的子组件内msg数据,在控制台显示“Welcome to Vue”
  },
  components:{HelloWorld}
};
</script>

二:兄弟关系组件:

  1. 兄弟之间传递数据需要借助事件车,通过事件车的方式传递数据
  2. 创建一个vue实例,让各个兄弟共同使用一个事件机制
  3. 传递数据方,通过一个事件触发bus.$emit(方法名,传递的数据)
  4. 接收数据方,通过mounted()触发bus.$on(方法名,function(接收数据的参数){用该数据接收的传递过来的数据}),此时函数中的this已经发生了改变,可以使用箭头函数。
    自己总结:(先单独创建一个eventVue.js文件,在兄弟组件中引入这个js事件,并且兄弟之间传递数据需要借助一个中间人,这个中间人可以是父组件,在父组件中引入兄弟组件,传递数据的组件通过触发bus.$emit事件传数据,接收数据的组件通过bus.$on接收参数,这样就达成了兄弟组件的传递)

举例子:

我们可以创建一个单独的js文件eventVue.js,内容如下

import Vue from 'vue'
export default new Vue

 假如父组件如下:

<template>
     <components-a></components-a>
     <components-b></components-b>
</template>

子组件a如下:

<template>
      <div class="components-a">
           <button @click="abtn">A按钮</button>
      </div>
</template>
<script>
import eventVue from '../../js/event.js'
export default {
      name: 'app',
      data () {
        return {
                ‘msg':"我是组件A"
        }
      },
      methods:{
           abtn:function(){
                   eventVue .$emit("myFun",this.msg)   //$emit这个方法会触发一个事件
           }
      }
}
</script>

 子组件b如下:

<template>
     <div class="components-a">
         <div>{
   
   {btext}}</div>
     </div>
</template>
<script>
import eventVue from '../../js/event.js'
export default {
   name: 'app',
   data () {
        return {
           'btext':"我是B组件内容"
        }
   },
   created:function(){
       this.bbtn();
   },
   methods:{
       bbtn:function(){
            eventVue .$on("myFun",(message)=>{   //这里最好用箭头函数,不然this指向有问题
                 this.btext = message      
            })
       }
    }
}
</script>

三:页面关系组件

在vuecli3.0以后,项目结构对组件级别作了明确的区别:入口组件(App) - 页级组件(View) - 零件组件(Component)。一般在开发中我们也会尽量按照这种结构去划分模块,但页级组件没有父组件,如果说页级组件之间需要传值,那就不能用“总线转送”的方法了。
vuex: 这是官方提供的一个插件,可称为“状态管理仓库”,用来管理项目中需要跨页共享反复调用的状态(状态你可以理解成就是数据、变量、方法)。

vuex的存放仓库为Store,内部结构可分五大块:
state: 状态库,寄放基础状态。
mutations: 同步方法,可理解成相当于组件内的computed属性,接收state进行改装。
actions: 异步方法,只针对mutations,接收并改装。
getters: 过滤器,对state调用前进行改装、派生并返回数据。
modules: 模块,在复杂项目中用modules处理Store,使分工更清晰。

自己总结

vuex:状态管理库,分5大模块:

  • state:状态库
  • mutations:相当于computed属性,改变state状态(同步方法)
  • actions:对mutations进行改变(异步方法)
  • getters:过滤器,对state调用前的状态进行修改
  • modules: 模块,处理Store,使分工更清晰

vue页面之间传值:

  1. 使用vue-router通过跳转链接带参数传参。
  2. 使用本地缓存localStorge。
  3. 使用vuex数据管理传值。

说说vue的动态组件

    多个组件通过同一个挂载点进行组件的切换,is的值是哪个组件的名称,那么页面就会显示哪个组件。

主要考查面试这 component的 is属性。

https://segmentfault.com/a/1190000019208626

https://zhuanlan.zhihu.com/p/33036996

5.Vue的路由实现:hash模式和history模式

hash模式:在浏览器中符号“#”,#以及#后面的字符称之为hash,用window.location.hash读取
URL:http://www.abc.com/#/hello hash 的值为 #/hello

特点:hash虽然在URL中,但不被包括在HTTP请求中;用来指导浏览器动作,对服务器安全无用,hash不会重加载页面

hash模式下,hash符号之前的内容会被包含在请求中。如 http://www.xxx.com,因此对于后端来说,即使没有做到对路由的全覆盖,也不会返回 404 错误。

history模式:它采用的是HTML5的新特性;且提供了2个新方法:pushState(),replaceState()可以对浏览器历史记录栈进行修改,以及popState事件的监听状态变更。history模式下,前端URL必须和实际向后端发起请求的URL一致,如http://www.xxx.com/items/id。后端如果缺少对 /items/id 的路由处理,将返回 404 错误。

6.Vue与React的区别?-------(不会)

相同点:

React采用特殊的JSX语法,Vue.js在组件开发中也推崇编写.vue特殊文件格式,对文件内容都有一些约定,两者都需要编译后使用;中心思想相同:一切都是组件,组件实例之间可以嵌套;都提供合理的钩子函数,可以让开发者定制化地去处理需求;

不同点:

React采用的Virtual DOM会对渲染出来的结果做脏检查;Vue.js在模板中提供了指令,过滤器等,可以非常方便,快捷地操作Virtual DOM。

7.vue的优点是什么?vue如何性能优化

可重用性:可以将公共部分抽取出组件

低耦合。使用了双向绑定原理

性能优化:

代码层面优化:

根据不用场景选择合适的条件

  1. v-show和v-if的使用(v-show:频繁的切换场景)
  2. computed 和 watch  区分使用场景

Webpack 层面的优化:

  1. Webpack 对图片进行压缩
  2. 提取公共代码,抽成公共组件
  3. 减少 ES6 转为 ES5 的冗余代码

https://www.jianshu.com/p/41d161310949

8.路由之间跳转

声明式(标签跳转<router-link to='home'>)

编程式(js跳转router.push(‘/home’))

vue -router声明式路由导航和编程式路由导航

前提:$router:路由器对象;$route:当前路由信息

一:声明式路由导航===>>>即:<router-link>

<router-link to='xxx' tag='li'> To PageB </router-link>

注意:<router-link>会默认解析成a标签,可以通过tag属性指定解析成什么标签

编式路由导航===>>>即写js的方式($router.push)

https://blog.csdn.net/crazywoniu/article/details/80942642?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param

编程式导航传递的参数有两种类型:字符串,对象

字符串

字符串的方式是直接将路由地址以字符串的方式来跳转,这种方式很简单但是不能传递参数

this.$router.push("home")

对象 

想要传递参数主要以对象的方式来写,分为两种方式:命名路由,查询参数,下面分别说明两种方式的用法和注意事项

命名路由

命名路由的前提就是注册路由的地方需要给路由命名

命名路由传递参数需要使用params来传递,这里一定要注意使用params不是query。目标 页面接收传递参数时使用params 

 特别注意:命名路由这种方式传递的参数,如果在目标页面刷新是会出错的

 使用方法如下:

this.$router.push({name: 'news', params: {userId: 123})

代码如下

<template>
  <div class="hello">
    <h1>{
   
   { msg }}</h1>
    <button @click="routerTo">click here to news page</button>
  </div>
</template>
 
<script>
export default {
  name: 'HelloWorld',
  data () {
    return {
      msg: 'Welcome to Your Vue.js App'
    }
  },
  methods:{
    routerTo(){
      this.$router.push({ name: 'news', params: { userId: 123 }});
    }
  }
}
</script>
 
<style>
</style>

 接受传递的参数:

<template>
  <div>
    this is the news page.the transform param is {
   
   {this.$route.params.userId}}
  </div>
</template>
<script>
  
</script>

查询参数

查询参数其实就是在路由地址后面带上参数和传统的url参数一致的,传递参数使用query而且必须配合path来传递参数而不能用name,目标页面接收传递的参数使用query。 

注意:和name配对的是params,和path配对的是query 

使用方法如下

this.$router.push({ path: '/news', query: { userId: 123 }});

代码如下:

<template>
  <div class="hello">
    <h1>{
   
   { msg }}</h1>
    <button @click="routerTo">click here to news page</button>
  </div>
</template>
 
<script>
export default {
  name: 'HelloWorld',
  data () {
    return {
      msg: 'Welcome to Your Vue.js App'
    }
  },
  methods:{
    routerTo(){
      this.$router.push({ path: '/news', query: { userId: 123 }});
    }
  }
}
</script>
 
<style>
</style>

 接收参数如下:

<template>
  <div>
    this is the news page.the transform param is {
   
   {this.$route.query.userId}}
  </div>
</template>
<script>
</script>

相关API

  • this.$router.push(path):相当于点击路由链接(可以返回当前路由页面)===>>>队列方式(先进先出)
  • this.$router.replace(path):用新路由替换当前路由(不可返回当前路由页面)===>>>栈的方式(先进后出)
  • this.$router.back():请求(返回)上一个记录路由
  • this.$router.go(-1):请求(返回)上一个记录路由
<div>
<ul>
<li v-for="(message,index) in messages" :key="message.id">
<router-link :to="`/home/message/detail/${message.id}`">{
   
   {message.title}}</router-link>
<button @click="pushShow(message.id)">push查看</button>
<button @click="replaceShow(message.id)">replace查看</button>
</li>
</ul>
<button @click="$router.back()">回退</button>
<hr />
<router-view></router-view>
</div>



methods:{
pushShow(id){
this.$router.push(`/home/message/detail/${id}`)
}
replaceShow(id){
this.$router.replace(`/home/message/detail/${id}`)
}
}

9.组件传值.sync   

 原理------vue子父组件传值

vue2.4版本后添加了.sync修饰符:可以在子组件中修改值

<HelloWorld :msg.sync="msg" @parentFun='change'/>   //使用sync修饰符//在父组件中监听msg是否发生了变化
watch:{			   
 msg:(newValue,oldValue)=>{				   
 console.log(oldValue);				
 console.log(newValue);
	}	
}

子组件中:要修改值需要出发函数  update:msg    : update是固定的,后面跟着的是变量   

changeMsg: function() {
     this.$emit('update:msg','hello')
     console.log(this.$props.msg)
},

11.vuex是什么?怎么使用?使用场景

全局存储数据用的-----状态管理

  • 在main.js引入store,注入。用来读取状态集中store中
  • 新建了一个目录store,….. export 。

场景:单页应用中,组件之间的状态

State:存放数据状态,不可直接修改里面数据

https://blog.csdn.net/LuckyandLucky/article/details/104209839?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase

先看这个:https://www.cnblogs.com/xihao/p/11420884.html

再看这个:https://segmentfault.com/a/1190000015782272

12.如何让css在当前组件中起作用

就在当前组件内使用,当前组件<style>写成<style  scoped>

13.怎么定义vue-router的动态路由以及如何获取传过来的动态参数?

在router目录下的index.js文件中,对path属性加上/:id

接收传递的参数 params.id

14.vue-router有哪几种导航钩子?

3种:

一种是全局导航钩子:router.beforeEach(to,from,next),

作用:

  • 跳转前进行判断拦截
  • to:route即将进入的目标路由对象
  • from:route当前导航正要离开的路由

next:function一定要调用该方法resolve这个钩子。执行效果依赖next方法的调用参数。可以控制网页的跳转。

第二种:组件内的钩子(组件声明周期):beforeRouteEnter, beforeRouteUpdate, beforeRouteleave

第三种:单独路由独享组件:beforeEnter

Vue中的钩子函数(https://segmentfault.com/a/1190000013956945

 钩子函数分为生命周期钩子路由守卫钩子

生命周期钩子

beforeCreate(){
      console.log('组件实例化之前')
  },
  created(){
      console.log('组件实例化完毕,单页面还未显示')
  },
  beforeMount(){
      console.log('组件挂载前,页面仍未展示,但虚拟Dom已经配置')
  },
  mounted(){
    console.log('组件挂在后,此方法执行后,页面显示')
 },
 beforeUpdate(){
     console.log('组件更新前,页面仍未更新,但虚拟Dom已经配置')
 },
 updated(){
     console.log('组件更新,此方法执行后,页面显示')
 },
 beforeDestroy(){
     console.log('组件销毁前')
 },
 destroyed(){
     console.log('组件销毁')
 },

路由守卫钩子

  • 全局守卫:router.beforeEach,  router.beforeResolve, router.afterEach
  • 路由独享守卫:beforeEnter
  • 组件内的守卫:beforeRouteEnter, beforeRouteUpdate, beforeRouteleave

 路由导航解析流程:???

  1. 导航被触发。
  2. 在失活的组件里调用离开守卫。
  3. 调用全局的 beforeEach 守卫。
  4. 在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
  5. 在路由配置里调用 beforeEnter
  6. 解析异步路由组件。
  7. 在被激活的组件里调用 beforeRouteEnter
  8. 调用全局的 beforeResolve 守卫 (2.5+)。
  9. 导航被确认。
  10. 调用全局的 afterEach 钩子。
  11. 触发 DOM 更新。
  12. 用创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数。

15.说出至少4种vue当中的指令和他的用法?

v-if

v-on:事件绑定

v-bind:class:绑定属性样式

<div class="static"
v-bind:class="{ active: isActive, 'text-danger': hasError }">
</div>
data: {
isActive: true,
hasError: false
}

v-modal:绑定数据

<template>
  <div>
    <div class="message">{
   
   { info.message }}</div>
    <div><input v-model="info.message" type="text"></div>
    <button @click="change">click</button>
  </div>
</template>

<script>
  export default {
    data () {
      return {
        info: {}
      }
    },
    methods: {
      change () {
        this.info.message = 'hello world'
      }
    }
  }
</script>

v-for:循环

v-bind(冒号就是v-bind的缩写,是为了动态绑定数据)

注意:

加上了冒号是为了动态绑定数据,等号后面可以写变量。

如果不使用冒号,等号后面就可以写字符串等原始类型数据。这时就无法进行动态绑定数据了。

16.vue-loader是什么?用途是什么?

解析.vue文件的一个加载器

用途:加载由 vue-loader 提取出的 CSS 代码

https://www.cnblogs.com/dream111/p/13498766.html

17.scss是什么?在vue.cli中的安装使用步骤是?有那几大特性?

css的预编译

第一步:先装css-loader、node-loader、sass-loader等加载器模块

第二步:在build目录找到webpack.base.config.js,在那个extends属性中加一个拓展.scss

第三步:在同一个文件,配置一个module属性

第四步:然后在组件的style标签加上lang属性 ,例如:lang=”scss”

特性:

可以用变量,例如($变量名称=值);
可以用混合器,例如()
可以嵌套

18.为什么使用key?

key作为唯一标识,当有相同标签名的元素切换时,需要通过key特性设置唯一的值来标记以让Vue区分它们,否则vue为了效率只会替换相同标签内部的内容

19.说出vue.cli项目中src目录每个文件夹和文件的用法?

  • assets文件夹放静态资源
  • components放组件
  • router是定义路由相关配置
  • view视图
  • app.vue是一个应用主组件
  • main.js是入口文件

20.vue.cli中怎么使用自定义组件?有遇到过哪些问题吗?

第一步:在components目录新建你的组件文件(smithButton.vue),script一定要export default {

第二步:在需要用的页面(组件)中导入:import smithButton from ‘…/components/smithButton.vue’

第三步:注入到vue的子组件的components属性上面,components:{smithButton}

第四步:在template视图view中使用,

问题:命名需要注意smithButton命名,使用的时候则smith-button。

21.active-class是哪个组件的属性?

vue-router模块的route-link组件

22.keep-alive

Vue 内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染。

https://www.jianshu.com/p/9523bb439950

23.v-if与v-show的区别?

  • v-show是css切换,如果,display:none在源码中也不显示   (block显示)
  • v-if条件渲染,是完整的销毁和重新创建       v-if="false",当为false时不会渲染页面

24.绑定class的数组用法

  • 对象方法:v-bind:class="{'name':'snsn','price':11}
  • 数组方法:v-bind:class="[class1,class2]"
  • 行内:v-bind:style="{color:color,fontSize:fontSize+'px}"

25.计算属性和watch的区别

computed:监听值,计算出一个新的值

get:读取当前属性值,根据计算并返回当前属性值

set:监听当前属性值的变化,当属性值变化时,更新相关属性数据

// 计算一个全名,fullName不可以在data中定义
data: {
   firstName: 's',
   lastName:'ss'
}
computed:{
fullName: {
get(){   //回调函数,读取当前属性值,根据计算并返回当前属性值
return this.firstName + this.lastName
},
set(val){ // 监事当前属性值的变化,当属性值变化时,更新相关属性数据
this.firstName = val[0]
this.lastName = val[1]
}
}
}

watch:监听值的变化,

它是一个对象,有哪些属性?

  • handler:深度监听对应的函数名必须为handler
  • deep:是否深度监听
  • immediate:是否立即执行
<div>
      <p>FullName: {
   
   {fullName}}</p>
      <p>FirstName: <input type="text" v-model="firstName"></p>
</div>
 
new Vue({
  el: '#root',
  data: {
    firstName: 'Dawei',
    lastName: 'Lou',
    fullName: ''
  },
  watch: {
    firstName(newName, oldName) {
      this.fullName = newName + ' ' + this.lastName;
    }
  } 
})
  • immediate和handler,deep
watch: {
  firstName: {
    handler(newName, oldName) {
      this.fullName = newName + ' ' + this.lastName;
    },
    // 代表在wacth里声明了firstName这个方法之后立即先去执行handler方法,如果设置了false,那么效果和上边例子一样
    immediate: true,
    deep: true
  }
}

computed 和 methods 有什么区别?

methods是一个方法,它可以接受参数,而computed不能,computed可以缓存,methods不会。

https://segmentfault.com/a/1190000014478664?utm_source=tag-newest

举个生活中例子

垃圾分类?为什么我们有可回收垃圾

就是可以把一些可回收的垃圾重复利用,避免了浪费。同样computed就是这个作用,把计算过的数据/处理过的利用缓存功能,存起来,进行资源的复用,避免不必要的请求,优化了用户体验。

computed 和 watch有什么区别?

computed:

  1. 计算值
  2. 应用:简化template里面{ {}}计算和处理props和$emit的传值
  3. 具有缓存性:页面重新渲染值不变化,计算属性会立即返回之前的计算结果,而不必再次执行函数

watch:

  1. 观察的动作
  2. 应用:监听props,$emit或本组件的值执行异步操作
  3. 无缓存性,页面重新渲染不发生变化也会执行 

26.事件修饰符

  • .stop事件:阻止冒泡事件发生
  • .prevent:防止事件加载跳转到下一个页面
  • .once:事件只执行一次

27.组件中data为什么是函数?(为什么组件中的 data 必须是一个函数,然后 return 一个对象,而 new Vue 实例里,data 可以直接是一个对象?)

因为组件是用来复用的,JS里对象是引用关系,这样作用域没有隔离。而new Vue的实例,是不会被复用的,因此不存在引用对象的问题。(一个组件的 data 选项必须是一个函数,每个实例可以维护一份被返回对象的独立的拷贝:)

data: function () {
  return {
    count: 0
  }
}

参考Vue官网:

https://cn.vuejs.org/v2/guide/components.html

https://cn.vuejs.org/v2/api/#Vue-extend

组件基础---组件的复用

28.怎么理解单向数据流

这个概念出现在组件通信。父组件是通过 prop 把数据传递到子组件的,但是这个 prop 只能由父组件修改,子组件不能修改,否则会报错。子组件想修改时,只能通过 $emit 派发一个自定义事件,父组件接收到后,由父组件修改。
一般来说,对于子组件想要更改父组件状态的场景,可以有两种方案:
在子组件的 data 中拷贝一份 prop,data 是可以修改的,但 prop 不能:

export default {
  props: {
    value: String
  },
  data () {
    return {
      currentValue: this.value
    }
  }
}

如果是对 prop 值的转换,可以使用计算属性:

export default {
  props: ['size'],
  computed: {
    normalizedSize: function () {
      return this.size.trim().toLowerCase();
    }
  }

29.slot插槽

单个插槽:

当子组件模板只有一个没有属性的插槽时,父组件传入的整个内容片段将插入到插槽所在的 DOM 位置,并替换掉插槽标签本身。

最初在 <slot> 标签中的任何内容都被视为备用内容。备用内容在子组件的作用域内编译,并且只有在宿主元素为空,且没有要插入的内容时才显示备用内容。

命名插槽:

solt元素可以用一个特殊的特性name来进一步配置如何分发内容。多个插槽可以有不同的名字。
这样可以将父组件模板中 slot 位置,和子组件 slot 元素产生关联,便于插槽内容对应传递

作用于插槽:

可以访问组件内部数据的可复用插槽(reusable slot)
在父级中,具有特殊特性 slot-scope 的<template> 元素必须存在,表示它是作用域插槽的模板。slot-scope 的值将被用作一个临时变量名,此变量接收从子组件传递过来的 prop 对象

https://www.cnblogs.com/mandy-dyf/p/11528505.html

30.css只在当前组件起作用。

在style标签中写入scoped即可。例如:<style scoped></style>

31.vue路由  动态路由  怎么动态添加路由

route和router的区别:

动态路由实际上指的是路由传参,比如列表调详情,动态添加路由是vue router中的addRoutes方法

  • route是“路由信息对象”,包括path,params,hash,query,fullPath,matched,name等路由信息参数。
  • router是“路由实例“对象包括路由的跳转方法,钩子函数

https://www.jianshu.com/p/51fb8003f312

https://www.cnblogs.com/dengyao-blogs/p/11562257.html

32.vue.js的两个核心是什么?

数据驱动,组件系统

33.v-on可以绑定多个方法吗?

可以

34.vue等单页面应用以及优缺点?

  • 优点:可以通过API实现响应的数据绑定和组合的视图组件
  • 缺点:如果数据很多,页面加载慢

35.this.$route.params与this.$route.query的区别。(开发中遇到什么问题?)

this.$route.query的使用

A:传参数

this.$router.push({
      path:'/custom',
      quuery:{
            id:id
       }
})

 B:接收参数

this.$route.query.id

C.在url中的形式(url带参数)

http://172.19.186.224:8080/#/monitor?id=1

D.页面之间用路由跳转传参时,刷新跳转后传参页面,数据还会显示存在。

this.$route.params的使用

A.传参

this.$router.push({
path:'/custom',
params:{
id:id
}
})

B:接收参数

this.$route.params.id

C.在url中的形式(url不带参数)

http://172.19.186.224:8080/#/monitor

D.页面之间用路由跳转传参时,刷新页面跳转传参的页面,数据不存在

37.封装组件的注意事项

数据从父组件传入

props属性中添加验证规则: 

props: {
  length: {
    type: [String],
    default: 3
  }
}

父组件中处理事件

处理事件的方法尽量写在父组件中,以保证通用组件中的数据不被污染。

 留一个slot

38.vue路由跳转方式有哪些?

 https://www.jianshu.com/p/7ebf759653f1

 39.Vue中mixin和extend的使用场景

mixin全局脱敏用过,还有返回按钮用过

 混入是全局注册的,使用时要小心,因为他会影响每一个之后创建的 Vue实例。当然使用恰当,他会帮你更的处理逻辑

40.路由拦截

 主要思路:

  • 登录成功的时候存一个状态
  • 例如存在localStorage里
  • 通过路由钩子判断一下

登录页面:sessionStorage.setItem("isLogin", true);

 loginApi.login(params).then((res) => {
        if (res.code == 1) {
          this.$toast("登录成功");
          sessionStorage.setItem("isLogin", true);
          // localStorage.setItem("token", res.token);
          this.$router.push({
            name: "invoiceList",
            query: {
              housecode: this.housecode,
              ownername: this.ownername,
            },
          });
        } else {
          this.$toast(res.message);
        }

 局部拦截的页面

41.Vue-引入图片的两种方式

 

42.vue更新数组时触发视图更新的方法

面试的时候回答:

  • 变异方法--会改变原始数组:push(),pop(),shift(),unshift(),splice(),sort(),reverse()
  • 非变异方法--不会改变原始数组,会返回一个新数组,可以用新数组替换旧数组:filter(),concat(),slice()

在实例创建完成之后添加心得属性,他不会触发视图。

解决办法:Vue.set( target, key, value )

  • target:要更改的数据源(可以是对象或者数组)
  • key:要更改的具体数据
  • value :重新赋的值 

=============================================================================

详解: 

举例子: 

example1.items = example1.items.filter(function (item) {
  return item.message.match(/Foo/)
})

 注意事项:

由于JS的限制,Vue不能检测以下变动的数组

  1. 当你利用索引直接设置一个项时,例如:vm.items[indexOfItem] = newValue
  2. 当你修改数组的长度时,例如:vm.items.length = newLength

举例子: 

var vm = new Vue({
  data: {
    items: ['a', 'b', 'c']
  }
})
vm.items[1] = 'x' // 不是响应性的
vm.items.length = 2 // 不是响应性的

 为了解决第一类问题,以下两种方式都可以实现和vm.items[indexOfItem] = newValue 相同的效果,同时也将触发状态更新:

// Vue.set
Vue.set(vm.items, indexOfItem, newValue)
// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)

你也可以使用vm.$set实例方法,该方法是全局方法 Vue.set 的一个别名:

vm.$set(vm.items, indexOfItem, newValue)

 为了解决第二类问题,你可以使用 splice:

vm.items.splice(newLength)

https://www.cnblogs.com/dream111/p/13520349.html 

44.axios和ajax优缺点的理解 

https://blog.csdn.net/changbozizf/article/details/105456089?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2~all~first_rank_v2~rank_v25-1-105456089.nonecase&utm_term=axios%E7%9A%84%E4%BC%98%E7%BC%BA%E7%82%B9

45.location.href的用法

location.href可直接获取当前路径

46.SPA首屏加载慢如何解决

  • 将公用的js库用script引入,让浏览器并行加载
  • 加loading,提高用户体验

47.delete和vue.delete删除数组区别

  • delete只是被删除的元素变成了empty/undefined其他元素的键值不变
  • Vue.delete直接删除数组改变了数组的键值
<template>
  <div class="vue-delete">
    <p class="title tag-blue">
      delete和Vue.delete删除数组的区别
    </p>
    <ul>
      <li :key="index" v-for="(item, index) in a">a---{
   
   {item}}</li>
    </ul>
    <button @click="handleA">处理a数组</button>
    <ul>
      <li :key="index" v-for="(item, index) in b">b---{
   
   {item}}</li>
    </ul>
    <button @click="handleB">处理b数组</button>
  </div>
</template>
<script>
export default {
  name: "vueDelete",
  data() {
    return {
      a: [1,2,3,4],
      b: [1,2,3,4],
    }
  },
  methods: {
    handleA() {
      delete this.a[1]
      this.$set(this.a)
      console.log(this.a)
    },
    handleB() {
      this.$delete(this.b, 1)
      console.log(this.b)
    }
  }
}
</script>

 

51.static和assets的区别

https://www.cnblogs.com/dream111/p/13499384.html

52.v-for与v-if的优先级

v-for优先级大于v-if,如果在同一个节点,就是先循环在判断

53.单页面与多页面的区别及优缺点 

https://www.cnblogs.com/dream111/p/13499363.html

54.渐进式框架的理解

是一套用于构建用户界面的渐进式框架。Vue 被设计为可以自底向上逐层应用。

37.聊聊对vue.js的template编译的理解 

微信小程序

1.请谈谈微信小程序主要目录和文件的作用?

  • App.js 项目的入口文件,写入全局的公共方法,像本地存储的数据;
  • App.json 底部tab, 标题栏和路等设置;
  • App.wxss 公共样式,引入iconfont等;
  • pages 里面包含一个个具体的页面;
  • index.json (配置当前页面标题和引入组件等);
  • index.wxml (页面结构--模板文件);
  • index.wxss (页面样式表);
  • index.js (页面的逻辑,请求和数据处理等);
  • project.config.json 项目配置文件,用得最多的就是配置是否开启https校验;

 2 请谈谈wxml与标准的html的异同?到其他

相同:都是用来描述页面的结构;

不同:

  • 多了一些 wx:if 这样的属性以及 { { }} 这样的表达式
  • WXML仅能在微信小程序开发者工具中预览,而HTML可以在浏览器内预览
  • 都由标签、属性等构成;
  • 标签名字不一样,且小程序标签更少,单一标签更多;
  • 组件封装不同, WXML对组件进行了重新封装,
  • 小程序运行在JS Core内,没有DOM树和window对象,小程序中无法使用window对象和document对象。

 3.请谈谈WXSS和CSS的异同?

相同:都是用来描述页面的样子;

不同:

  • WXSS 具有 CSS 大部分的特性,也做了一些扩充和修改;
  • WXSS新增了尺寸单位,WXSS 在底层支持新的尺寸单位rpx;
  • WXSS 仅支持部分 CSS 选择器;
  • WXSS 提供全局样式与局部样式

4.你是怎么封装微信小程序的数据请求的?

1.在根目录下创建api目录及index.js文件和request.js文件;

2.在request.js 封装基础的get, post 和 put,delete方法和一个请求公共的方法,创建函数设置请求体,带上token和异常处理等;

                

3.根据页面数据请求的需要, 导出增删改查4个方法

 4.index.js-------------->是写请求接口的,引入4个方法,并根据不同接口使用不同函数

5.在具体的页面中导入;

5 小程序页面间有哪些传递数据的方法?

  • 使用全局变量实现数据传递
  • 页面跳转或重定向时,使用url带参数传递数据
  • 使用组件模板 template传递参数
  • 使用缓存传递参数
  • 使用数据库传递数据

6.请谈谈小程序的双向绑定和vue的异同?

大体相同,但小程序直接this.data的属性是不可以同步到视图的,必须调用this.setData()方法!

7 请谈谈小程序的生命周期函数?

  • 生命周期函数-onLoad: 页面加载;(一个页面只会调用一次)
  • onShow() 页面显示/切入前台时触发,一般用来发送数据请求;(每次打开页面都会调用一次)
  • onReady() 页面初次渲染完成时触发(一个页面只会调用一次,代 表页面已经准备妥当,可以和视图层进行交互)
  • onHide() 页面隐藏(当navigateTo或底部tab切换时调用)
  • onUnload() 页面卸载时触发,如redirectTo或navigateBack到其他页面时

8 简述微信小程序原理?

  • 小程序本质就是一个单页面应用,所有的页面渲染和事件处理,都在一个页面内进行,但又可以通过微信客户端调用原生的各种接口;
  • 它的架构,是数据驱动的架构模式,它的UI和数据是分离的,所有的页面更新,都需要通过对数据的更改来实现;
  • 它从技术讲和现有的前端开发差不多,采用JavaScript、WXML、WXSS三种技术进行开发;
  • 功能可分为webview和appService两个部分;
  • webview用来展现UI,appService有来处理业务逻辑、数据及接口调用;
  • 两个部分在两个进程中运行,通过系统层JSBridge实现通信,实现UI的渲染、事件的处理等。

9.小程序视图渲染结束回调?

使用setData(data, callback),在callback回调方法中添加后续操作代码

10.this.setData

赋值用的,会让页面重新渲染,如果直接用data里赋值,页面不会重新渲染,与vue的不同之处

11.方法传值

问题:点击方法怎么获得传的值?

可以data-参数名 = "传的值"    wxml

e.currentTarget.dataset.属性值 js

接收值:options.属性值

12.小程序2点间距离

获取当前用的地理位置   wx.getlocal

用wx.getlocal拿到经纬度,再用后台返的经纬度,再在前端方法计算2点间距离

PC端

1.引入腾讯地图js文件

2.页面创建一个节点(div)

3.初始化新建地图实例的一个方法

搜索:通过调用腾讯地图的API实现

13.e:事件对象

14.json:小程序页面的配置

例如:页面标题,颜色什么的都可以在这里面设置

主要文件:

app.json   全局配置  tarBar

app.js       入口文件必须有的

15.小程序页面间有哪些传递数据的方法

var app = get App()

app:存储全局变量或者存在本地

缓存中:localStorage:用于微信小程序自己的方法

16.小程序跳转方式有几种?

  • wx.navigateTo:          正常跳转可以返回
  • wx.redirectTo             跳转后当前页面关闭
  • wx:relanuch           跳转页面后所有页面
  • wx:swichTab          调到tab页
  • 前3个不能跳转到tab页

17.wxss和css有哪些不一样

在css上做了一些补充和修改

  1. 单位:rpx
  2. 用import引入外部样式

例如:2个页面相同样式比较多就可以用引入  的方式

18.如何提高微信小程序的应用速度?

  1. 提高页面加载速度
  2. 用户行为预测
  3. 组件化方案

19.组件间通信

https://www.cnblogs.com/fps2tao/p/11368357.html

20.前端分页--分页

22.组件传值 

1.父组件引用子组件

父组件json文件中(局部的)

 "usingComponets":{

"customerSelector":"/compnents/customerSelector/index"

    }

子组件中json

{
  "component": true
}

2.父组件中给组件传的值

<empty-image tableList="{
   
   {tableList.list}}"></empty-image>

 3.子组件接收

// 无数据
Component({
  properties: {
    tableList: {
      type: Array,
      value: []
    }
  }
})

2:子组件传值给父组件

子组件在需要传值时,使用triggerEvent传给父组件一个事件( myevent ),并传递想要给父组件的值( sonParam )

在父组件中,子组件的引用处,通过这个myevent事件绑定一个方法( onMyEvent )

在父组件的js中,定义这个方法onMyEvent,在这个方法内就可以获取到子组件传递过来的值了

23.app.json 是对当前小程序的全局配置,讲述三个配置各个项的含义? 

  • pages字段 —— 用于描述当前小程序所有页面路径,这是为了让微信客户端知道当前你的小程序页面定义在哪个目录。
  • window字段 —— 小程序所有页面的顶部背景颜色("navigationBarBackgroundColor": "#fff"”,),文字颜色定义在这里的
  • tab字段—小程序全局顶部或底部tab

24.小程序的wxss和css有哪些不一样的地方? 

新像素单位 rpx样式可直接使用import导入

1、尺寸单位 rpx

rpx 是响应式像素,可以根据屏幕宽度进行自适应。规定屏幕宽为 750rpx。如在 iPhone6 上,屏幕宽度为 375px,共有 750 个物理像素,则 750rpx = 375px = 750 物理像素

2、使用 @import 标识符来导入外联样式。@import 后跟需要导入的外联样式表的相对路径,用;表示语句结束

/** index.wxss **/

@import './base.wxss';

.container{
    color: red;
}

 25.小程序有哪些参数传值的方法?

给HTML元素添加data-属性来传递我们需要的值,然后通过e.currentTarget.dataset或onload的param参数获取。但data-名称不能有大写字母和不可以存放对象;
设置id 的方法标识来传值通过e.currentTarget.id获取设置的id的值,然后通过设置全局对象的方式来传递数值;
在navigator中添加参数传值。

26.小程序简单介绍下三种事件对象的属性列表?  

  • 基础事件(BaseEvent)
  1. type: 事件类型
  2. timeStamp:事件生成时的时间戳
  3. target:触发事件的组件的属性值集合
  4. currentTarget:当前组件的一些属性集合
  • 自定义事件(CustomEvent)
  1. detail
  • 触摸事件(TouchEvent)
  1. touches
  2. changedTouches

27.小程序关联微信公众号如何确定用户的唯一性?

使用wx.getUserInfo方法 withCredentials为true时,可获取encryptedData,里面有union_id.后端需要进行对称解密。

28.微信小程序如何实现下拉刷新? 

用view代替scroll-view,设置onPullDownRefresh函数实现,在json文件中设为enablePullDownRefresh:true

29.bindtap和catchtap的区别? 

  • bind事件绑定不会阻止冒泡事件向上冒泡
  • catch事件绑定可以阻止冒泡事件向上冒泡

30.rpx:小程序的尺寸单位,规定屏幕为750rpx,可适配不同分辨率的屏幕。

31.页面栈及路由跳转

路由是由一个栈维护的,这个页面栈的长度是有限的。小程序页面栈存放最多10个。

https://blog.csdn.net/qq_42049445/article/details/104536394

 33.tabBar设置不显示

  1. tabBar的数量少于2项或超过5项都不会显示;
  2. tabBar写法错误导致不显示; 

34.微信小程序登录流程

1.调用wx.login()获取临时登录凭证code,并回传到开发者服务器

35.授权

 wx.getSetting

1.浏览器的存储方式有哪些?

React面试题

1.React是什么?React有什么特点

一个用来构建用户界面的 JavaScript 库。

  • 有什么特点?

它用于虚拟DOM,组件化设计模式声明式代码单向数据流使用JSX描述信息等特点

  • 什么是虚拟DOM?

用于构建虚拟的HTML的DOM

  • 什么是组件化设计模式?

可复用的代码可以抽成组件共同使用(UI,方法等)

  • 声明式代码(编程)思想:

就是你的目的是什么,应该怎么做,但是具体不说明怎么做。

举例子:去酒吧告诉服务员点一杯鸡尾酒,服务员给你一杯鸡尾酒就好,但是具体怎么做的没有说

  • 还有其他的编程方式吗?

命令式编程

https://blog.csdn.net/sinat_30990593/article/details/86562440

  • 对比:

相对比而言,声明式编程

  1. 更加简洁、易懂,利于大型项目代码的维护;
  2. 无须使用变量,避免了创建和修改状态;
  • 什么是单向数据流呢?

像瀑布的水一样,从上往下流,这个水就是组件的数据流。

 所以组件父组件的数据流向子组件,子组件就用props读取值

  • 什么是JSX呢?

JSX就是js的扩展语言

jsx语法=js语法+html语法

  • react主要功能如下:
  1. 它使用虚拟DOM,而不是真正的DOM
  2. 他可以进行服务器端渲染
  3. 它遵循单向数据流或数据绑定

2.React的优点和缺点 

优点: 

  • 提高了应用性能和开发效率
  • 用JSX,代码可读性好
  • react的componentWillUnmount生命周期,能够清除相关所有事件,避免内存泄露
  • 并不直接对DOM进行操作,引入了一个虚拟DOM的概念,安插在javascript逻辑和实际的DOM之间,性能好,速度快

缺点:

https://blog.csdn.net/weixin_42052388/article/details/80902388

3.Vue与React两个框架的区别对比

相似之处:

  • 用于创建UI的js库
  • 使用起来轻快,便捷
  • 都用了虚拟DOM
  • 都是基于组件的架构

不同点: 

  • vue通常使用html模板,react用的是js
  • vue有双向绑定
  • vue增加了语法糖computed和watch,而在React中需要自己写一套逻辑来实现
  • vue用了指令(v-bind...),让模板可以更容易实现功能,react用的是jsx语法
  • react整体思路是编程式,推崇纯组件,数据不变,单向数据流。vue数据可变,双向绑定,声明式的写法

https://www.jianshu.com/p/4c812465ae97 

4.React的工作原理 

React 会创建一个虚拟 DOM(virtual DOM)。当一个组件中的状态改变时,React 首先会通过 "diffing" 算法来标记虚拟 DOM 中的改变,第二步是调节(reconciliation),会用 diff 的结果来更新 DOM。

6.JSX是什么?jsx代码到显示内容的转换过程

它是js和xml(html)语法的组合 

JSX是JavaScript XML的缩写,是一个JavaScript的语法扩展,本质上是JavaScript对象。JSX可以很好的描述UI信息,但是浏览器无法直接读取,编译的过程中会将JSX转换成JavaScript的对象结构。

7.Real DOM和Virtual DOM

React不直接操作DOM,而是实现了Virtual DOM,组件DOM结构映射到这个虚拟DOM上 。React在虚拟DOM上实现了differ算法,当要重新渲染组件的时候,会通过diff寻找到要变更的DOM节点,再把这个修改更新到浏览器实际上的DOM节点

为什么虚拟DOM会提高性能

虚拟DOM相当于在JS和真实DOM中间加了一个缓存,利用diff减少了没有必要的操作,从而提高了性能,本质上是JS对象。 

  • 虚拟DOM 是映射真实DOM的js对象数据结构
  • 采用虚拟DOM ,避免直接操作真实的DOM,提升性能
  • 当状态更新时,重新渲染新的虚拟DOM,采用diff算法对比新旧DOM,进行视图更新

8.阻止React的默认行为 

e.preventDefault() ,,,e是第三方提供的一个合成事件

注意:不能用return 

class App extends React.component{
constructor(props){
super(props);
this.state = {
}
}

hander(e){
e.preventDefault()
}
render(){
return <button onClick={ this.hander.bind(this) }>阻止事件</button>
}
}

9.向事件处理程序传递参数

 例如删除当前行的id

<button onClick={(e) => this.delete(e,id)}>Delete Row<button>
<button onClick={this.delete.bind(this,id)}>Delete Row</button>

10.React中key作用是什么?

作用(目的):key是用于追踪哪些列表中元素被修改删除或者被添加辅助标识。在diff算法中,key用来判断该元素节点是被移动过来的还是新创建的元素,减少不必要的元素重复渲染

11.当渲染一个列表时,何为 key?

Keys 会有助于 React 识别哪些 items 改变了,被添加了或者被移除了。Keys 应该被赋予数组内的元素以赋予(DOM)元素一个稳定的标识,选择一个 key 的最佳方法是使用一个字符串,该字符串能惟一地标识一个列表项。很多时候你会使用数据中的 IDs 作为 keys,当你没有稳定的 IDs 用于被渲染的 items 时,可以使用项目索引作为渲染项的 key,但这种方式并不推荐,如果 items 可以重新排序,就会导致 re-render 变慢

9.React中diff算法

diff算法的作用是用来计算出Virtual DOM中被改变的部分,然后针对该部分进行原生DOM的操作,而不用重新渲染整个页面。

diff算法有三种策略:

  • tree diff:DOM节点跨层级的移动操作特别少,可以忽略不计。
  • component diff:拥有相同类的两个组件生成相似的数据结构;拥有不同类的两个组件生成不同的树形结构。
  • element diff:对于同一层级的一组子节点,通过唯一id区分。

diff算法原理:

  • 将树形结构按照层级分解,只比较同级元素。
  • 给列表结构的每个单元添加唯一的key属性,方便比较。
  • React只会匹配相同class的component
  • 合并操作,调用component的setState方法的时候,React将其标记为dirty,到每一轮事件循环结束,React检查所有标记dirty的component重新渲染。
  • 选择性子树渲染。开发人员可以重新shouldComponentUpdate提高diff的性能。

 10.React中Element与Component

Element是描述屏幕上课件内容的数据结构,是对UI对象的标书

Component是可以接受参数输入并且返回某个ReactElement的函数或者类 

11.props和state((组件的)状态(state)和属性(props)之间有何不同)

  • state 是数据结构,会随着事件推移发送变化,只能使用setState来改变
  • props 是组件的属性,由父组件传递给子组件,props是不可变的

state是局部的,除了它所在的这个组件其他组件都无法访问

没有设置state的组件叫无状态组件设置了state的组件有状态组件

有状态组件通过继承component来构建,一个子类就是一个组件;无状态组件通过函数式声明来构建,一个函数就是一个组件。

12.React可以用两种方法声明组件(Component),他们的区别是什么,什么情况你会选择哪一种?(React中有哪些构建组件的方式)

 函数组件(Function Components):首字母要大写,需要return出react元素

function Welcome(props){
return (
<h1>hello world</h1>
)
}

类组件(Class Components):首字母要大写,需要使用render方法,return出react元素

class Welcome extends React.Component{
        render(){
            return (
            <div>11</div>
        )
    }
}

区别:

  • 函数组件看似只是一个返回值是DOM结构的函数,其实它的背后是无状态组件的思想。
  • 函数组件中,你无法使用State,也无法使用组件的生命周期方法,这就决定了函数组件都是展示性组件,接收Props,渲染DOM,而不关注其他逻辑
  • 函数组件中没有this
  • 函数组件更容易理解。当你看到一个函数组件时,你就知道它的功能只是接收属性,渲染页面,它不执行与UI无关的逻辑处理,它只是一个纯函数。而不用在意它返回的DOM结构有多复杂

13.简单的聊聊生命周期(指出(组件)生命周期方法的不同)

  • constuctor:在构造函数中初始化props和state 
  • componentWillMount -- 在组件渲染之前执行对state进行最后的修改
  • render - 渲染
  • componentDidMount -- 在组件渲染之后执行,
  • componentWillReceiveProps -- 这个周期函数作用于特定的 prop 改变导致的 state 转换
  • shouldComponentUpdate -- 用来做性能优化的,是否允许改变组件更新,返回true是允许继续往下执行,,可以返回false,用来阻止组件更新。当一个父组件更新时,它下面有很多子组件也会一起更新,当有可能大部门子组件都没有变化,如何全部更新都会造成消耗性能,可以在子组件中设置return false来避免不必要的更新
  • componentWillUpdate -- 数据在改变之前执行
  • componentDidUpdate -- 数据修改完成,常用于更新 DOM,响应 prop 或 state 的改变
  • componentWillUnmount -- 组件卸载前执行。在这你可以取消网络请求,或者移除所有与组件相关的事件监听器

14.什么是单向数据流和状态提升

 单向数据流:从上往下父组件将state数据流向子组件,子组件通过props取值

像瀑布的水一样,从上往下流,这个水就是组件的数据流。

状态提升:组件之间的数据交互

举例子:如果两个组件都需要用到对方的状态,那么这时候就可以用到状态提升。具体做法是把两个子组件的状态写到他们的父组件中,然后父组件把状态传递给子组件的props中去,这样子组件也相当于有状态。

父组件

import React from "react"
import Child1 from "./child1"
import Child2 from "./child2"

export default class Parent extends React.Component {

    constructor() {
        super()
        this.state = {
            money: 1
        }
    }

    changeHander(e){
        this.setState({
            money: e.target.value
        })
    }
    render() {
        return (
            <div>
                <input type="text" value={ this.state.money } onChange={this.changeHander.bind(this)} />
                <p>Parent</p>
                人民比: <Child1 money={this.state.money} />
                美金: <Child2 money={this.state.money} />
            </div>
        )
    }
}

子组件1

import React from "react"

export default class Child1 extends React.Component{

    constructor(){
        super()
        this.state = {
            input1: 0
        }
    }

    componentDidMount(){
        this.setState({
            input1: this.props.money
        })
    }

    changeHander(e) {
        this.setState({
             input1: e.target.value
        })
    }

    render() {
        return(
            <div>
                 { this.props.money }
               <input type="text" value={ this.state.input1 } onChange={ this.changeHander.bind(this) }/>
            </div>
        )
    }
}

 子组件2

import React from "react"

export default class Child2 extends React.Component{

    constructor(){
        super();
        this.state = {
            input2: 1
        }
    }

    componentDidMount(){
        this.setState({
            input2: this.props.money * 7
        })
    }

    changeHander(e) {
        this.setState({
             input2: e.target.value
        })
    }
    render() {
        return(
            <div>
                { this.props.money * 7}
               <input type="text" value={ this.state.input2 } onChange={ this.changeHander.bind(this) }/>
            </div>
        )
    }
}

17.调用setState之后发生了什么

setState会进行状态更新
将传入的参数对象与组件当前的状态合并,然后触发所谓的调和过程(Reconciliation),经过调和过程,根据新的state,React元素会重新构建虚拟DOM,进行DIFF算法对比新旧虚拟DOM树的区别,进行视图更新,而不是全部渲染

setState 采用的任务队列机制,不会马上执行,而是加入队列,在下次事件循环是一次性执行

18.为什么建议传递给setState的参数是一个callback而不是一个对象(不懂)

因为this.props和this.state的更新可能是异步的,不能依赖它们的值去计算下一个state 

19.关于this绑定

1.bind
<button onClick={this.handleClick.bind(this)}>hello</button>
2.在构造函数中默认绑定this
this.handleClick = this.handleClick.bind(this)
3.使用箭头函数来处理
<button onClick={ (e) => this.handleClick(e) }>Click me</button>

20.setState第二个参数的作用(不懂)

该函数会在setState函数调用完成并且组件开始重新渲染的时候被调用,我们可以用该函数来监听渲染是否完成 

21.在构造函数中调用super(props)目的是什么?(不懂)

在super()调用之前,子类是不能使用this的,ES5中,子类必须在constructor中调用super().传递props给super()的原因则是便于能在constructor访问this.props

22.flux的思想和流程

 Flux的最大特点,就是数据的”单向流动“

流程:

用户访问view

view发送给用户的action

dispatcher接收action,要求store进行相应的更新

store更新后,发送一个change事件

view收到change事件后,更新页面

23.createElement和cloneElement有什么区别

  •  createElement函数是JSX编译之后使用的创建React Element的函数
  • cloneElement则是用于复制某个元素并传入新的props 

24.展示组件(presentational component)和容器组件(Container component)之间有何不同

展示组件关心组件看起来是什么。展示专门通过 props 接受数据和回调,并且几乎不会有自身的状态,但当展示组件拥有自身的状态时,通常也只关心 UI 状态而不是数据的状态。

容器组件则更关心组件是如何运作的。容器组件会为展示组件或者其它容器组件提供数据和行为(behavior),它们会调用 Flux actions,并将其作为回调提供给展示组件。容器组件经常是有状态的,因为它们是(其它组件的)数据源。

25.类组件(Class component)和函数式组件(Function component)之间有什么不同

  • 类组件不仅允许你使用更多额外的功能,如组件自身的状态和生命周期钩子,也能使组件直接访问 store 并维持状态
  • 当组件仅是接收 props,并将组件自身渲染到页面时,该组件就是一个 '无状态组件(stateless component)',可以使用一个纯函数来创建这样的组件。这种组件也被称为哑组件(dumb components)或展示组件

26.应该在React组件的何处发起Ajax请求

在 React 组件中,应该在 componentDidMount 中发起网络请求。这个方法会在组件第一次“挂载”(被添加到 DOM)时执行,在组件的生命周期中仅会执行一次。更重要的是,你不能保证在组件挂载之前 Ajax 请求已经完成,如果是这样,也就意味着你将尝试在一个未挂载的组件上调用 setState,这将不起作用。在 componentDidMount 中发起网络请求将保证这有一个组件可以更新了。

27.何为受控组件(controlled component)

在HTML中,像<input>,<textarea><select>这类表单元素会维持自身状态,并根据用户输入进行更新,但是React中,可变的状态是保存在组件的状态属性中的,只能通过setState来进行更新(value的值可以改变)
受控组件就是让两者合二为一,其值由React控制的输入表单元素称为‘受控组件

例如:10个人从A通道上公交车,第二个人选择了不坐,从B通道走了,第三个人就变为第二个人上车的(更新state),上车的人就是受控元素

或者是淘宝买东西,订单3个商品,你想在再买一个,然后提交,商品有3变成4,这也是一个更新state,然后提交,表单中的元素都是受控元素

非受控组件

value值只读 

28.在React中,refs的作用是什么

Refs 可以用于获取一个 DOM 节点或者 React 组件的引用。何时使用 refs 的好的示例有管理焦点/文本选择,触发命令动画,或者和第三方 DOM 库集成。你应该避免使用 String 类型的 Refs 和内联的 ref 回调。Refs 回调是 React 所推荐的。

29.何为高阶组件(higher order component)

高阶组件是一个以组件为参数并返回一个新组件的函数。HOC 运行你重用代码、逻辑和引导抽象。最常见的可能是 Redux 的 connect 函数。除了简单分享工具库和简单的组合,HOC最好的方式是共享 React 组件之间的行为。如果你发现你在不同的地方写了大量代码来做同一件事时,就应该考虑将代码重构为可重用的 HOC。

30.使用箭头函数的优点是什么

  • 作用域安全:在箭头函数之前,每一个新创建的函数都有定义自身的 this 值(在构造函数中是新对象;在严格模式下,函数调用中的 this 是未定义的;如果函数被称为“对象方法”,则为基础对象等),但箭头函数不会,它会使用封闭执行上下文的 this 值。
  • 简单:箭头函数易于阅读和书写
  • 清晰:当一切都是一个箭头函数,任何常规函数都可以立即用于定义作用域。开发者总是可以查找 next-higher 函数语句,以查看 this 的值

31.除了在构造函数中绑定this,还有其它方式吗?

你可以使用属性初始值设定项(property initializers)来正确绑定回调,create-react-app 也是默认支持的。在回调中你可以使用箭头函数,但问题是每次组件渲染时都会创建一个新的回调。

32.怎么阻止组件的渲染

在组件的 render 方法中返回 null 并不会影响触发组件的生命周期方法 

33.(在构造函数中)调用super(props)的目的是什么

super() 被调用之前,子类是不能使用 this 的,在 ES2015 中,子类必须在 constructor 中调用 super()。传递 propssuper() 的原因则是便于(在子类中)能在 constructor 访问 this.props

34.怎么用React.createElement重写下面的代码

https://www.jianshu.com/p/4357c4ae99eb 

35.在react中,何为state

State 和 props 类似,但它是私有的,并且完全由组件自身控制。State 本质上是一个持有数据,并决定组件如何渲染的对象。 

36.什么圆心会促使你脱离create-react-app的以来

当你想去配置 webpack 或 babel presets。 

37.何为redux,对Redux的工作原理的理解,以及redux中间件的工作原理

Redux 的基本思想是整个应用的 state 保持在一个单一的 store 中。store 就是一个简单的 javascript 对象,而改变应用 state 的唯一方式是在应用中触发 actions,然后为这些 actions 编写 reducers 来修改 state。整个 state 转化是在 reducers 中完成,并且不应该有任何副作用

38.在Redux中,何为store

Store 是一个 javascript 对象,它保存了整个应用的 state。与此同时,Store 也承担以下职责:

  • 允许通过 getState() 访问 state
  • 运行通过 dispatch(action) 改变 state
  • 通过 subscribe(listener) 注册 listeners
  • 通过 subscribe(listener) 返回的函数处理 listeners 的注销

39.何为action

Actions 是一个纯 javascript 对象,它们必须有一个 type 属性表明正在执行的 action 的类型。实质上,action 是将数据从应用程序发送到 store 的有效载荷。 

40.何为纯函数

一个纯函数是一个不依赖于且不改变其作用域之外的变量状态的函数,这也意味着一个纯函数对于同样的参数总是返回同样的结果。 

41.通信

React中的组件通信有以下几种情况:

  • 父子组件通信
  • 兄弟组件通信
  • 跨多层次组件通信
  • 任意组件通信

父子组件通信:父组件通过props传递参数给子组件,子组件通过调用父组件传来的函数传递数据给父组件。

兄弟组件通信:通过使用共同的父组件来管理状态和事件函数。一个组件通过父组件传来的函数修改父组件的状态,父组件再将状态传递给另一个子组件。

跨多层次组件通信:使用Context API。

任意组件:使用Redux或者Event Bus。

42.React-Router

React-Router是一个基于React之上的强大路由库,它可以让你向应用中快速地添加视图和数据流,同时保持页面与URL间的同步。

Router用于定义多个路由,当用户定义特定的URL时,如果此URL与Router内定义的任何“路由”的路径匹配,则用户将重定向到该特定路由。

43.当你调setState的时候,发生了什么

 简述一下redux

redux是一个状态管理器框架,解决组件间状态共享的问题,原理是集中式管理,主要有三个核心方法,action,store, reducer
工作流程:
view调用store 的dispatch方法接收action传入store,
reducer进行state 更新
通过store.getState()获取最新的state,进行视图更新
缺点:

  • 一个组件所需要的数据,必须由父组件传过来,而不能直接从store中获取
  • 当一个组件相关数据更新时,即使父组件不需要用到这个组件,父组件还是会重新render,需要shouldComponentUpdate 进行优化

44.shouldComponentUpdate应该做什么?为什么他们很重要

45.为什么浏览器无法读取JSX?

浏览器只能处理js对象,而不能读取常规js对象中的jsx.所以为了使浏览器能够读取JSX.首先,需要向Babel这样的jsx转换器将jsx文件转换为js对象,然后再将其传给浏览器。

46.与es5相比,React的es6语法有何不同?

https://segmentfault.com/a/1190000018604138

HTTP面试题

1.HTTP有哪些请求方法?

HTTP1.0定义了3中方法:GET,POST,HEAD

HTTP1.1新增了5种请求:OPTIONS,PUT,DELETE,TRACE和CONNECT

2.以上方法具体有什么作用?

  • GET:请求指定的页面信息,并返回实体主体
  • POST: 请求服务器接受所指定的文档作为对所标识的URI的新的从属实体。
  • PUT:从客户端向服务器传送的数据取代指定的文档的内容。
  • DELETE: 请求服务器删除指定的页面的数据。
  • HEAD:  只请求页面的首部。
  • OPTIONS:允许客户端查看服务器的性能

3.GET和POST有什么区别?

  1. 数据传输不同:GET请求通过URL传输数据,而POST的数据通过请求体传输
  2. 安全性不同:POST数据因为在请求体内,所以有一定的安全性保证;而GET的数据在URL中,通过历史记录,缓存很容易查到数据信息

4..什么是幂等性

幂等不管进行多少次重复操作,都是实现相同的结果.

5.REST请求中哪些是幂等操作(rest:前后台通信的一种方式)

  • GET,PUT,DELETE都是幂等操作,而POST不是
  • GET请求很好理解,对资源做查询多次,此实现的结果都是一样的。
  • PUT请求的幂等性可以这样理解,将A修改为B,它第一次请求值变为了B,再进行多次此操作,最终的结果还是B,与一次执行的结果是一样的,所以PUT是幂等操作。
  • 同理可以理解DELETE操作,第一次将资源删除后,后面多次进行此删除请求,最终结果是一样的,将资源删除掉了。
  • POST不是幂等操作,因为一次请求添加一份新资源,二次请求则添加了两份新资源,多次请求会产生不同的结果,因此POST不是幂等操作。(对于POST请求,两次调用POST请求,可能就会在服务器创建两份资源,所以当然不是幂等的。)

6.PUT和POST都是给服务器发送资源的,有什么区别?

区别:幂等性(PUT方法是幂等的:连续调用一次或者多次的效果相同(无副作用),而POST方法是非幂等的。)

我们在开发一个博客系统,当我们要创建一篇文章的时候往往用POST https://www.jianshu.com/articles,这个请求的语义是,在articles的资源集合下创建一篇新的文章,如果我们多次提交这个请求会创建多个文章,这是非幂等的。

PUT https://www.jianshu.com/articles/820357430的语义是更新对应文章下的资源(比如修改作者名称等),这个URI指向的就是单一资源,而且是幂等的,比如你把『刘德华』修改成『蔡徐坤』,提交多少次都是修改成『蔡徐坤』

GET和POST方法区别?

  • get重点在从服务器上获取资源,post重点在向服务器发送数据
  • get传输数据是通过URL请求,以field(字段)= value的形式,置于URL后,并用"?"连接,多个请求数据间用"&"连接,如http://127.0.0.1/Test/login.action?name=admin&password=admin,这个过程用户是可见的;
    post传输数据通过Http的post机制,将字段与对应值封存在请求实体中发送给服务器,这个过程对用户是不可见的;
  • Get传输的数据量小,因为受URL长度限制,但效率较高;
    Post可以传输大量数据,所以上传文件时只能用Post方式;(自己总结:get传输数据量小,但是高效;post传输数据量大)
  • get是不安全的,因为URL是可见的,可能会泄露私密信息,如密码等;
    post较get安全性较高;(自己总结:post安全性比get高)
  • get方式只能支持ASCII字符,向服务器传的中文字符可能会乱码。
    post支持标准字符集,可以正确传递中文字符。(get只支持ASCII字符;post支持标准字符集)

7.PUT和PATCH都是给服务器发送修改资源,有什么区别?

PUT和PATCH都是更新资源,而PATCH用来对已知资源进行局部更新.

比如我们有一篇文章的地址https://www.jianshu.com/articles/820357430,这篇文章的可以表示为:

article = {
    author: 'dxy',
    creationDate: '2019-6-12',
    content: '我写文章像蔡徐坤',
    id: 820357430
}

当我们要修改文章的作者时,我们可以直接发送PUT https://www.jianshu.com/articles/820357430,这个时候的数据应该是

{
    author:'蔡徐坤',
    creationDate: '2019-6-12',
    content: '我写文章像蔡徐坤',
    id: 820357430
}

这种直接覆盖资源的修改方式应该用put,但是你觉得每次都带有这么多无用的信息,那么可以发送PATCH https://www.jianshu.com/articles/820357430,这个时候只需要:

{
    author:'蔡徐坤',
}

8.http的请求报文是什么样的?

请求报文有4部分组成:

  • 请求行:请求方法,地址,http版本信息.他们用空格分隔.例如, GET /index.html HTTP/1.1
  • 请求头部:由关键字和值组成,用英文冒号分隔;
  • 空行
  • 请求体

 

  • 请求体: post put等请求携带的数据

9.http的响应报文是什么样的?

请求报文有4部分组成:

  • 响应行:由协议版本,状态码和状态码原因短语组成;例如HTTP/1.1 200 OK
  • 响应头:响应部首组成
  • 空行
  • 响应体:服务器响应的数据

10.HTTP的部首有哪些?

// ✨重点

通用首部字段(请求报文与响应报文都会使用的首部字段)

  • Cache-Control  控制缓存 ✨(比说)
  • Connection 连接管理、逐条首部
  • Date 创建报文的日期✨(必说)
  • Transfor-Encoding 报文主体的传输编码格式 ✨(必说)

请求首部字段(请求报文会使用的首部字段)

  • Accept 客户端请求的浏览器类型
  • Accept-Encoding 优先可处理的编码格式
  • Accept-Language 优先可处理的自然语言✨
  • Accept-Charset 优先可以处理的字符集
  • Authorization web的认证信息 ✨(必说)
  • Host 请求资源所在服务器
  • User-Agent 客户端程序信息

响应首部字段(响应报文会使用的首部字段)

  • Accept-Ranges 能接受的字节范围
  • Location 令客户端重定向的URI
  • Server 服务器的信息
  • ETag 能够表示资源唯一资源的字符串 ✨

实体首部字段(请求报文与响应报文的的实体部分使用的首部字段)

  • Allow 资源可支持http请求的方法 ✨                  // Allow:GET, HEAD
  • Content-Language 实体的资源语言✨               //Content-Lanuage: zh-CN
  • Content-Encoding 实体的编码格式✨                   // Content-Encoding: gizp    
  • Content-Length 实体的大小(字节)✨              // Content-Length: 15000
  • Content-Type 实体媒体类型
  • Content-Range实体主体的位置返回✨
  • Last-Modified 资源最后的修改资源 ✨
  • Expires 实体主体的过期资源 ✨
    https://www.cnblogs.com/insane-Mr-Li/p/10142445.html

11.HTTP的状态码有哪些?

2XX 成功

  • 200 OK,表示从客户端发来的请求在服务器端被正确处理 ✨(请求成功)
  • 204 No content,表示请求成功,但响应报文不含实体的主体部分
  • 206 Partial Content,进行范围请求 

3XX 重定向

  • 301 moved permanently,永久性重定向,表示资源已被分配了新的 URL
  • 302 found,临时性重定向,表示资源临时被分配了新的 URL ✨(重定向,临时被分配新的url)
  • 303 see other,表示资源存在着另一个 URL,应使用 GET 方法丁香获取资源
  • 304 not modified,表示服务器允许访问资源,但因发生请求未满足条件的情况
  • 307 temporary redirect,临时重定向,和302含义相同

4XX 客户端错误

  • 400 bad request,请求报文存在语法错误 ✨(请求无效,提交数据的字段名与后端要的不一样)https://www.cnblogs.com/beppezhang/p/5824986.html
  • 401 unauthorized,表示发送的请求需要有通过 HTTP 认证的认证信息 ✨(token失效)https://blog.csdn.net/ShiMengRan107/article/details/101781145
  • 403 forbidden,表示对请求资源的访问被服务器拒绝 ✨(一般为跨域问题,请求头不一样)
  • 404 not found,表示在服务器上没有找到请求的资源 ✨(请求路径不对)
  • 408 Request timeout, 客户端请求超时(请求超时)

5XX 服务器错误

  • 500 internal sever error,表示服务器端在执行请求时发生了错误
  • 503 service unavailable,服务器正忙

12.同样是重定向307,303,302的区别?同样是重定向307,303,302的区别?

302是http1.0的协议状态码,在http1.1版本的时候为了细化302状态码又出来了两个303和307。

303明确表示客户端应当采用get方法获取资源,他会把POST请求变为GET请求进行重定向。 307会遵照浏览器标准,不会从post变为get。

13.为什么有了HTTP为什么还要HTTPS?

https是安全版的http,因为http协议的数据都是明文进行传输的,所以对于一些敏感信息的传输就很不安全,HTTPS就是为了解决HTTP的不安全而生的。

14.HTTPS是如何保证安全的?

对称加密:即通信的双方都使用同一个秘钥进行加解密,比如特务接头的暗号,就属于对称加密

对称加密虽然很简单性能也好,但是无法解决首次把秘钥发给对方的问题,很容易被hacker拦截秘钥。

非对称加密:

  1. 私钥 + 公钥= 密钥对
  2. 即用私钥加密的数据,只有对应的公钥才能解密,用公钥加密的数据,只有对应的私钥才能解密
  3. 因为通信双方的手里都有一套自己的密钥对,通信之前双方会先把自己的公钥都先发给对方
  4. 然后对方再拿着这个公钥来加密数据响应给对方,等到到了对方那里,对方再用自己的私钥进行解密

非对称加密虽然安全性更高,但是带来的问题就是速度很慢,影响性能。

解决方案:

那么结合两种加密方式,将对称加密的密钥使用非对称加密的公钥进行加密,然后发送出去,接收方使用私钥进行解密得到对称加密的密钥,然后双方可以使用对称加密来进行沟通。

此时又带来一个问题,中间人问题:

如果此时在客户端和服务器之间存在一个中间人,这个中间人只需要把原本双方通信互发的公钥,换成自己的公钥,这样中间人就可以轻松解密通信双方所发送的所有数据。

所以这个时候需要一个安全的第三方颁发证书(CA),证明身份的身份,防止被中间人攻击。

证书中包括:签发者、证书用途、使用者公钥、使用者私钥、使用者的HASH算法、证书到期时间等

2019-06-14-12-30-18

但是问题来了,如果中间人篡改了证书,那么身份证明是不是就无效了?这个证明就白买了,这个时候需要一个新的技术,数字签名。

数字签名就是用CA自带的HASH算法对证书的内容进行HASH得到一个摘要,再用CA的私钥加密,最终组成数字签名。

当别人把他的证书发过来的时候,我再用同样的Hash算法,再次生成消息摘要,然后用CA的公钥对数字签名解密,得到CA创建的消息摘要,两者一比,就知道中间有没有被人篡改了。

这个时候就能最大程度保证通信的安全了。

14.Http与Https的区别:

  1. HTTP 的URL 以http:// 开头,而HTTPS 的URL 以https:// 开头
  2. HTTP 是不安全的,而 HTTPS 是安全的
  3. HTTP 标准端口是80 ,而 HTTPS 的标准端口是443
  4. 在OSI 网络模型中,HTTP工作于应用层,而HTTPS 的安全传输机制工作在传输层
  5. HTTP 无法加密,而HTTPS 对传输的数据进行加密
  6. HTTP无需证书,而HTTPS 需要CA机构wosign的颁发的SSL证书

15.一次完整的HTTP请求所经历的7个步骤

https://www.cnblogs.com/linjiqin/p/3560152.html 

HTTP通信机制是在一次完整的HTTP通信过程中,Web浏览器与Web服务器之间将完成下列7个步骤:

1. 建立TCP连接 

在HTTP工作开始之前,Web浏览器首先要通过网络与Web服务器建立连接,该连接是通过TCP来完成的,该协议与IP协议共同构建Internet,即著名的TCP/IP协议族,因此Internet又被称作是TCP/IP网络。HTTP是比TCP更高层次的应用层协议,根据规则,只有低层协议建立之后才能进行更高层协议的连接,因此,首先要建立TCP连接,一般TCP连接的端口号是80。

2. Web浏览器向Web服务器发送请求命令

一旦建立了TCP连接,Web浏览器就会向Web服务器发送请求命令。例如:GET/sample/hello.jsp HTTP/1.1。

16.HTTP1.1版本新特性

  • 默认持久连接节省通信量,只要客户端服务端任意一端没有明确提出断开TCP连接,就一直保持连接,可以发送多次HTTP请求
  • 管线化,客户端可以同时发出多个HTTP请求,而不用一个个等待响应
  • 断点续化(实际上就是利用http消息头使用分块传输编码,将实体主体分块传输)

17.TCP/IP面试整理

https://blog.csdn.net/qq_40086556/article/details/82017916

一般如何处理用户敏感信息?  

 前端一般使用‘’、sha1加密,想要了解详情请自行百度。

浏览从输入网址到回车发生了什么;  

通俗的说:

搜索浏览器自身的缓存(浏览器会检查是否有响应的cookie)

搜索本机其他浏览器缓存

host解析

前端安全性问题(CSRF、XSS) 

https://blog.csdn.net/a401461843/article/details/77622299/

跨站脚本攻击(XSS攻击)

XSS是常见的Web攻击术之一。所谓的跨站脚本攻击指的是: 恶意攻击者往Web页面注入恶意Script代码,用户浏览这些网页的时候,就会执行这些代码,从而窃取用户得cookie信息.

解决方案:输入过滤:对用户输入的数据做一定的过滤。如输入的格式是否符合条件,像电话号

 跨域请求伪造(CSRF攻击):是一中常见Web攻击

CSRF攻击过程的受害者用户登录网站A,输入个人信息,在本地保存服务器生成的cookie。然后在A网站点击由攻击者构建一条恶意链接跳转到B网站,然后B网站携带着的用户cookie信息去访问B网站.让A网站造成是用户自己访问的假相,从而来进行一些列的操作,常见的就是转账.

解决办法:手机验证码

文件上传漏洞:

解决方案:

  1. 检查服务器是否判断了文件上传类型及后缀
  2. 定义上传文件为白名单,即只有白名单里面类型的文件可以上传

前端跨域、浏览器缓存、cookie, session, token, localstorage, sessionstorage;

 TCP连接(三次握手, 四次挥手)

https://blog.csdn.net/qq_35860138/article/details/82054793 

WEB前端性能

https://blog.csdn.net/holily_/article/details/102622686

Html:

  1. 避免代码的深层及嵌套。因为层级越深在初始化的时候越占内存
  2. 尽量少使用html5丢弃的iframe标签,因为在页面加载时候回先加载iframe标签,加载完在加载其他的标签
  3. 像img,link,script等元素的src或者href的属性值不为空,就算我们写src=””浏览器仍然会发送请求
  4. 在html文档开始就指定字符集。这样做目的是有助于浏览器加载时能立即解析html代码

CSS部分:

  1. 少使用!Important
  2. 公共样式抽取,减少代码冗余,重复的样式
  3. 用link代替@important
  4. 将样式置顶,这样做好处是文档加载完之前样式就已经加载完,不用等样式加载完毕后再加载

JS

  1. 尽量减少全局变量,和全局方法的定义
  2. 用setTimeout或者加载loading避免页面失去响应
  3. 尽量减少多余代码,公共代码进行封装

优化网站性能:

  1. 减少http请求:合并文件
  2. 减小cookie大小
  3. 将js和css从外部引入
  4. 优化图片

React面试题

git面试题

1.强制推送                git push -- force

2.克隆远程代码

git clone url

3.查看提交日志

git log

4.拉取远程代码自动合并到当前分支(超级好用的命令)

git pull origin 分支名

5.查看分支本地分支

git branch

6.查看远程分支

git branch -a

7.本地新建分支a

git branch 分支a

8.将当前分支切换到 分支a

git checkout 分支a

猜你喜欢

转载自blog.csdn.net/qq_40055200/article/details/104637574