2020web前端面试总结(建议收藏)

一、CSS问题

web前端全栈资料粉丝福利(面试题、视频、资料笔记、进阶路线)

1.flex布局

display:flex; 在父元素设置,子元素受弹性盒影响,默认排成一行,如果超出一行,按比例压缩 flex:1; 子元素设置,设置子元素如何分配父元素的空间,flex:1,子元素宽度占满整个父元素align-items:center 定义子元素在父容器中的对齐方式,center 垂直居中justify-content:center 设置子元素在父元素中居中,前提是子元素没有把父元素占满,让子元素水平居中。

2.css3的新特性

transtion transition-property 规定设置过渡效果的 CSS 属性的名称。

transition-duration 规定完成过渡效果需要多少秒或毫秒。

transition-timing-function 规定速度效果的速度曲线。

transition-delay 定义过渡效果何时开始。

animation属性可以像Flash制作动画一样,通过控制关键帧来控制动画的每一步,实现更为复杂的动画效果。

ainimation实现动画效果主要由两部分组成:

通过类似Flash动画中的帧来声明一个动画;

在animation属性中调用关键帧声明的动画。

translate 3D建模效果

3.img中alt和title的区别

图片中的 alt属性是在图片不能正常显示时出现的文本提示。alt有利于SEO优化

图片中的 title属性是在鼠标在移动到元素上的文本提示。

4.用纯CSS创建一个三角形

<style>

    div {

        width: 0;

        height: 0;

        border-top: 40px solid transparent;

        border-left: 40px solid transparent;

        border-right: 40px solid transparent;

        border-bottom: 40px solid #ff0000;

    }

    </style>

</head>

<body>

  <div></div>

</body>

5.如何理解CSS的盒子模型?

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

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

6.如何让一个div水平居中

已知宽度,block元素 ,添加添加margin:0 auto属性。

已知宽度,绝对定位的居中 ,上下左右都为0,margin:auto

7.如何让一个div水平垂直居中

div {

position: relative / fixed; /* 相对定位或绝对定位均可 */

width:500px;

height:300px;

top: 50%;

left: 50%;

margin-top:-150px;

margin-left:-250px;

外边距为自身宽高的一半 */

background-color: pink; /* 方便看效果 */

}

.container {

display: flex;

align-items: center; /* 垂直居中 */

justify-content: center; /* 水平居中 */

}

.container div {

width: 100px; /* 可省 */

height: 100px; /* 可省 */

background-color: pink; /* 方便看效果 */

8.如何清除浮动?

clear清除浮动(添加空div法)在浮动元素下方添加空div,并给该元素写css样式 {clear:both;height:0;overflow:hidden;}

给浮动元素父级设置高度

父级同时浮动(需要给父级同级元素添加浮动)

父级设置成inline-block,其margin: 0 auto居中方式失效

给父级添加overflow:hidden 清除浮动方法

万能清除法 after伪类 清浮动(现在主流方法,推荐使用)

float_div:after{

content:".";

clear:both;

display:block;

height:0;

overflow:hidden;

visibility:hidden;

}

.float_div{

zoom:1

}

9.css3实现三栏布局,左右固定,中间自适应

圣杯布局/双飞翼布局

<style>

        * {

            margin: 0;

            padding: 0;

        }

        .middle,

        .left,

        .right {

            position: relative;

            float: left;

            min-height: 130px;

        }

        .container {

            padding: 0 220px 0 200px;

            overflow: hidden;

        }

        .left {

            margin-left: -100%;

            left: -200px;

            width: 200px;

            background: red;

        }

        .right {

            margin-left: -220px;

            right: -220px;

            width: 220px;

            background: green;

        }

        .middle {

            width: 100%;

            background: blue;

            word-break: break-all;

        }

    </style>

</head>

<body>

    <div class='container'>

        <div class='middle'></div>

        <div class='left'></div>

        <div class='right'></div>

    </div>

</body>

10.display:none 和 visibility: hidden的区别

display:none 隐藏对应的元素,在文档布局中不再给它分配空间,它各边的元素会合拢,就当他从来不存在。

visibility:hidden 隐藏对应的元素,但是在文档布局中仍保留原来的空间。

11.CSS中 link 和@import 的区别是?

link属于HTML标签,而@import是CSS提供的页面被加载的时,link会同时被加载,而@import引用的CSS会等到页面被加载完再加载

import只在IE5以上才能识别,而link是HTML标签,无兼容问题

link方式的样式的权重 高于@import的权重.

12.position的absolute与fixed共同点与不同点

共同点: 改变行内元素的呈现方式,display被置为block 让元素脱离普通流,不占据空间 默认会覆盖到非定位元素上

不同点: absolute的”根元素“是可以设置的 fixed的”根元素“固定为浏览器窗口。当你滚动网页,fixed元素与浏览器窗口之间的距离是不变的。

13..transition和animation的区别

Animation和transition大部分属性是相同的,他们都是随时间改变元素的属性值,他们的主要区别是transition需要触发一个事件才能改变属性, 而animation不需要触发任何事件的情况下才会随时间改变属性值,并且transition为2帧,从from .... to,而animation可以一帧一帧的。

transition 规定动画的名字 规定完成过渡效果需要多少秒或毫秒 规定速度效果 定义过渡效果何时开始 animation 指定要绑定到选择器的关键帧的名称

14.CSS优先级

不同级别:总结排序:!important > 行内样式>ID选择器 > 类选择器 > 标签 > 通配符 > 继承 > 浏览器默认属性

1.属性后面加!import 会覆盖页面内任何位置定义的元素样式

2.作为style属性写在元素内的样式

3.id选择器

4.类选择器

5.标签选择器

6.通配符选择器(*)

7.浏览器自定义或继承

**同一级别:后写的会覆盖先写的**

css选择器的解析原则:选择器定位DOM元素是从右往左的方向,这样可以尽早的过滤掉一些不必要的样式规则和元素

15.雪碧图:

多个图片集成在一个图片中的图

使用雪碧图可以减少网络请求的次数,加快允许的速度

通过background-position,去定位图片在屏幕的哪个位置

二、JS问题

1.typeof和instance of 检测数据类型有什么区别?

相同点: 都常用来判断一个变量是否为空,或者是什么类型的。

不同点: typeof 返回值是一个字符串,用来说明变量的数据类型 instanceof 用于判断一个变量是否属于某个对象的实例.

16.使元素消失的方法

多个图片集成在一个图片中的图

使用雪碧图可以减少网络请求的次数,加快允许的速度

通过background-position,去定位图片在屏幕的哪个位置

.谈一谈深克隆和浅克隆?

浅克隆: 只是拷贝了基本类型的数据,而引用类型数据,复制后也是会发生引用,我们把这种拷贝叫做“(浅复制)浅拷贝”,换句话说,浅复制仅仅是指向被复制的内存地址,如果原地址中对象被改变了,那么浅复制出来的对象也会相应改变。

深克隆: 创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。

JSON.parse、JSON.stringify()

3.es6的新特性都有哪些?

let定义块级作用域变量 没有变量的提升,必须先声明后使用 let声明的变量,不能与前面的let,var,conset声明的变量重名

const 定义只读变量 const声明变量的同时必须赋值,const声明的变量必须初始化,一旦初始化完毕就不允许修改 const声明变量也是一个块级作用域变量 const声明的变量没有“变量的提升”,必须先声明后使用 const声明的变量不能与前面的let, var , const声明的变量重 const定义的对象\数组中的属性值可以修改,基础数据类型不可以

ES6可以给形参函数设置默认值

在数组之前加上三个点(...)展开运算符

数组的解构赋值、对象的解构赋值

箭头函数的特点 箭头函数相当于匿名函数,是不能作为构造函数的,不能被new 箭头函数没有arguments实参集合,取而代之用...剩余运算符解决 箭头函数没有自己的this。他的this是继承当前上下文中的this 箭头函数没有函数原型 箭头函数不能当做Generator函数,不能使用yield关键字 不能使用call、apply、bind改变箭头函数中this指向 Set数据结构,数组去重

4.==和===区别是什么?

=赋值

==返回一个布尔值;相等返回true,不相等返回false; 允许不同数据类型之间的比较; 如果是不同类型的数据进行,会默认进行数据类型之间的转换; 如果是对象数据类型的比较,比较的是空间地址

=== 只要数据类型不一样,就返回false;

5.常见的设计模式有哪些?

1、js工厂模式

2、js构造函数模式

3、js原型模式

4、构造函数+原型的js混合模式

5、构造函数+原型的动态原型模式

6、观察者模式

7、发布订阅模式

6.call bind apply 的区别?

call() 和apply()的第一个参数相同,就是指定的对象。这个对象就是该函数的执行上下文。

call()和apply()的区别就在于,两者之间的参数。

call()在第一个参数之后的 后续所有参数就是传入该函数的值。

apply() 只有两个参数,第一个是对象,第二个是数组,这个数组就是该函数的参数。 bind() 方法和前两者不同在于: bind() 方法会返回执行上下文被改变的函数而不会立即执行,而前两者是 直接执行该函数。他的参数和call()相同。

7.js继承方式有哪些?

原型链继承 核心: 将父类的实例作为子类的原型

构造继承 核心:使用父类的构造函数来增强子类实例,等于是复制父类的实例属性给子类

实例继承 核心:为父类实例添加新特性,作为子类实例返回

拷贝继承

组合继承 核心:通过调用父类构造,继承父类的属性并保留传参的优点,然后通过将父类实例作为子类原型,实现 函数复用

寄生组合继承 核心:通过寄生方式,砍掉父类的实例属性,这样,在调用两次父类的构造的时候,就不会初始化两次实 例方法/属性,避免的组合继承的缺点

8.你怎样看待闭包?

个人感觉,简单来说闭包就是在函数里面声明函数,本质上说就是在函数内部和函数外部搭建起一座桥梁,使得子函数可以访问父函数中所有的局部变量,但是反之不可以,这只是闭包的作用之一,另一个作用,则是保护变量不受外界污染,使其一直存在内存中,在工作中我们还是少使用闭包的好,因为闭包太消耗内存,不到万不得已的时候尽量不使用。

9.你是如何理解原型和原型链的?

把所有的对象共用的属性全部放在堆内存的一个对象(共用属性组成的对象),然后让每一个对象的 __proto__存储这个「共用属性组成的对象」的地址。而这个共用属性就是原型,原型出现的目的就是为了减少不必要的内存消耗。而原型链就是对象通过__proto__向当前实例所属类的原型上查找属性或方法的机制,如果找到Object的原型上还是没有找到想要的属性或者是方法则查找结束,最终会返回undefined

10.浏览器渲染的主要流程是什么?

将html代码按照深度优先遍历来生成DOM树。 css文件下载完后也会进行渲染,生成相应的CSSOM。 当所有的css文件下载完且所有的CSSOM构建结束后,就会和DOM一起生成Render Tree。 接下来,浏览器就会进入Layout环节,将所有的节点位置计算出来。 最后,通过Painting环节将所有的节点内容呈现到屏幕上。

11.从输入url地址到页面相应都发生了什么?

1、浏览器的地址栏输入URL并按下回车。

2、浏览器查找当前URL是否存在缓存,并比较缓存是否过期。3、DNS解析URL对应的IP。

4、根据IP建立TCP连接(三次握手)。

5、HTTP发起请求。

6、服务器处理请求,浏览器接收HTTP响应。

7、渲染页面,构建DOM树。

8、关闭TCP连接(四次挥手)

12.session、cookie、localStorage的区别

相同点 都是保存在浏览器端,且同源的。

不同点

cookie数据始终在同源的http请求中携带,即cookie在浏览器和服务器间来回传递。

而sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。

cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下。 存储大小限制也不同,cookie数据不能超过4k,同时因为每次http请求都会携带cookie,所以cookie只适合保存很小的数据。

sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。 数据有效期不同,sessionStorage:仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持;

localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;

cookie只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。 作用域不同,sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;

localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。

13.js中跨域方法

同源策略(协议+端口号+域名要相同)

1、jsonp跨域(只能解决get) 原理:动态创建一个script标签。利用script标签的src属性不受同源策略限制,因为所有的src属性和href属性都不受同源策略的限制,可以请求第三方服务器资源内容

步骤: 1).去创建一个script标签 2).script的src属性设置接口地址 3).接口参数,必须要带一个自定义函数名,要不然后台无法返回数据 4).通过定义函数名去接受返回的数据

2、document.domain 基础域名相同 子域名不同

3、window.name 利用在一个浏览器窗口内,载入所有的域名都是共享一个window.name

4、服务器设置对CORS的支持 原理:服务器设置Access-Control-Allow-Origin HTTP响应头之后,浏览器将会允许跨域请求

5、利用h5新特性window.postMessage()

14.前端有哪些页面优化方法?

减少 HTTP请求数

从设计实现层面简化页面

合理设置 HTTP缓存

资源合并与压缩

合并 CSS图片,减少请求数的又一个好办法。

将外部脚本置底(将脚本内容在页面信息内容加载后再加载)

多图片网页使用图片懒加载。

在js中尽量减少闭包的使用

尽量合并css和js文件

尽量使用字体图标或者SVG图标,来代替传统的PNG等格式的图片

减少对DOM的操作

在JS中避免“嵌套循环”和 “死循环”

尽可能使用事件委托(事件代理)来处理事件绑定的操作

15.Ajax的四个步骤

1.创建ajax实例

2.执行open 确定要访问的链接 以及同步异步

3.监听请求状态

4.发送请求

16.数组去重的方法

ES6的set对象 先将原数组排序,在与相邻的进行比较,如果不同则存入新数组

function unique(arr){

    var arr2 = arr.sort();

    var res = [arr2[0]];

    for(var i=1;i<arr2.length;i++){

        if(arr2[i] !== res[res.length-1]){

        res.push(arr2[i]);

    }

}

return res;

}

利用下标查询

function unique(arr){

    var newArr = [arr[0]];

    for(var i=1;i<arr.length;i++){

        if(newArr.indexOf(arr[i]) == -1){

        newArr.push(arr[i]);

    }

}

return newArr;

}

17.ajax中get和post请求的区别

get 一般用于获取数据

get请求如果需要传递参数,那么会默认将参数拼接到url的后面;然后发送给服务器;

get请求传递参数大小是有限制的;是浏览器的地址栏有大小限制;

get安全性较低

get 一般会走缓存,为了防止走缓存,给url后面每次拼的参数不同;放在?后面,一般用个时间戳

post 一般用于发送数据

post传递参数,需要把参数放进请求体中,发送给服务器;

post请求参数放进了请求体中,对大小没有要求;

post安全性比较高;

post请求不会走缓存;

18.ajax的状态码

2开头

200 : 代表请求成功;

3开头

301 : 永久重定向;

302: 临时转移

304 : 读取缓存 [表示浏览器端有缓存,并且服务端未更新,不再向服务端请求资源]

307:临时重定向

以4开头的都是客户端的问题;

400 :数据/格式错误

401: 权限不够;(身份不合格,访问网站的时候,登录和不登录是不一样的)

404 : 路径错误,找不到文件

以5开头都是服务端的问题

500 : 服务器的问题

503: 超负荷;

19.移动端的兼容问题

给移动端添加点击事件会有300S的延迟 如果用点击事件,需要引一个fastclick.js文件,解决300s的延迟 一般在移动端用ontouchstart、ontouchmove、ontouchend

移动端点透问题,touchstart 早于 touchend 早于click,click的触发是有延迟的,这个时间大概在300ms左右,也就是说我们tap触发之后蒙层隐藏, 此时 click还没有触发,300ms之后由于蒙层隐藏,我们的click触发到了下面的a链接上 尽量都使用touch事件来替换click事件。例如用touchend事件(推荐)。 用fastclick,github.com/ftlabs/fast… 用preventDefault阻止a标签的click 消除 IE10 里面的那个叉号 input:-ms-clear{display:none;}

设置缓存 手机页面通常在第一次加载后会进行缓存,然后每次刷新会使用缓存而不是去重新向服务器发送请求。如果不希望使用缓存可以设置no-cache。

圆角BUG 某些Android手机圆角失效 background-clip: padding-box; 防止手机中网页放大和缩小 这点是最基本的,做为手机网站开发者来说应该都知道的,就是设置meta中的viewport

设置用户截止缩放,一般写视口的时候就已经写好了。

20.JS中同步和异步,以及js的事件流

同步:在同一时间内做一件事情

异步:在同一时间内做多个事情 JS是单线程的,每次只能做一件事情,JS运行在浏览器中,浏览器是多线程的,可以在同一时间执行多个任务。

21.JS中常见的异步任务

定时器、ajax、事件绑定、回调函数、async await、promise

22.TCP的三次握手和四次挥手

三次握手

第一次握手:客户端发送一个SYN码给服务器,要求建立数据连接;

第二次握手: 服务器SYN和自己处理一个SYN(标志);叫SYN+ACK(确认包);发送给客户端,可以建立连接

第三次握手: 客户端再次发送ACK向服务器,服务器验证ACK没有问题,则建立起连接;

四次挥手

第一次挥手: 客户端发送FIN(结束)报文,通知服务器数据已经传输完毕;

第二次挥手: 服务器接收到之后,通知客户端我收到了SYN,发送ACK(确认)给客户端,数据还没有传输完成

第三次挥手: 服务器已经传输完毕,再次发送FIN通知客户端,数据已经传输完毕

第四次挥手: 客户端再次发送ACK,进入TIME_WAIT状态;服务器和客户端关闭连接;

23.为什么建立连接是三次握手,而断开连接是四次挥手呢?

建立连接的时候, 服务器在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。 而关闭连接时,服务器收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,而自己也未必全部数据都发送给对方了,所以己方可以立即关闭,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送,从而导致多了一次。

24.DOM diff原理

如果元素类型发生变化,直接替换

如果是文本,则比较文本里面的内容,是否有差异,如果是元素就需要比较当前元素的属性是否相等,会先比较key, 在比较类型 为什么 react中循环 建议不要使用索引 ,如果纯为了展示 那可以使用索引

25.作用域

全局作用域

浏览器打开一个页面时,浏览器会给JS代码提供一个全局的运行环境,那么这个环境就是全局作用域 一个页面只有一个全局作用域,全局作用域下有一个window对象 window是全局作用域下的最大的一个内置对象(全局作用域下定义的变量和函数都会存储在window下) 如果是全局变量,都会给window新增一个键值对;属性名就是变量名,属性值就是变量所存储的值 如果变量只被var过,那么存储值是undefined 在私有作用域中是可以获取到全局变量的,但是在全局作用域中不能获取私有变量

私有作用域

函数执行会形成一个新的私有的作用域(执行多次,形成多个私有作用域) 私有作用域在全局作用域中形成,具有包含的关系; 在一个全局作用域中,可以有很多个私有作用域 在私有作用域下定义的变量都是私有变量 形参也是私有变量 函数体中通过function定义的函数也是私有的,在全局作用域不能使用;

块级作用域

es6中新引入的一种作用域 在js中常见到的if{}、for{}、while{}、try{}、catch{}、switch case{}都是块级作用域 var obj = {} //对象的大括号不是块级作用域 块级作用域中的同一变量不能被重复声明(块级下var和function不能重名,否则会报错) 作用域链

上级作用域

函数在哪里定义,他的上一级作用域就是哪,和函数在哪个作用域下执行没有关系 作用域链:当获取变量所对应的值时,首先看变量是否是私有变量,如果不是私有变量,要继续向上一级作用域中查找,如果上一级也没有,那么会继续向上一级查找,直到找到全局作用域为止;如果全局作用域也没有,则会报错;这样一级一级向上查找,就会形成作用域链 当前作用域没有的,则会继续向上一级作用域查找 当前函数的上一级作用域跟函数在哪个作用域下执行没有关系,只跟函数在哪定义有关(重点)

26.Promise处理异步

他是ES6中新增加的一个类(new Promise),目的是为了管理JS中的异步编程的,所以把他称为“Promise设计模式” new Promise 经历三个状态:padding(准备状态:初始化成功、开始执行异步的任务)、fullfilled(成功状态)、rejected(失败状态)== Promise本身是同步编程的,他可以管理异步操作的(重点),new Promise的时候,会把传递的函数立即执行 Promise函数天生有两个参数,resolve(当异步操作执行成功,执行resolve方法),rejected(当异步操作失败,执行reject方法) then()方法中有两个函数,第一个传递的函数是resolve,第二个传递的函数是reject ajax中false代表同步,true代表异步,如果使用异步,不等ajax彻底完成

27.map和forEach的区别

相同点

都是循环遍历数组中的每一项 forEach和map方法里每次执行匿名函数都支持3个参数,参数分别是item(当前每一项)、index(索引值)、arr(原数组),需要用哪个的时候就写哪个 匿名函数中的this都是指向window 只能遍历数组

不同点

map方法返回一个新的数组,数组中的元素为原始数组调用函数处理后的值。(原数组进行处理之后对应的一个新的数组。) map()方法不会改变原始数组 map()方法不会对空数组进行检测 forEach()方法用于调用数组的每个元素,将元素传给回调函数.(没有return,返回值是undefined)

注意:forEach对于空数组是不会调用回调函数的。

28.async await函数

async/await函数是异步代码的新方式

async/await是基于promise实现的

async/await使异步代码更像同步代码

await 只能在async函数中使用,不能再普通函数中使用,要成对出现

默认返回一个promise实例,不能被改变

await下面的代码是异步,后面的代码是同步的

29.this指向

全局作用域下的this指向window

如果给元素的事件行为绑定函数,那么函数中的this指向当前被绑定的那个元素

函数中的this,要看函数执行前有没有 . , 有 . 的话,点前面是谁,this就指向谁,如果没有点,指向window

自执行函数中的this永远指向window

定时器中函数的this指向window

构造函数中的this指向当前的实例

call、apply、bind可以改变函数的this指向

箭头函数中没有this,如果输出this,就会输出箭头函数定义时所在的作用域中的this

30.原型

所有的函数数据类型都天生自带一个prototype属性,该属性的属性值是一个对象 prototype的属性值中天生自带一个constructor属性,其constructor属性值指向当前原型所属的类 所有的对象数据类型,都天生自带一个_proto_属性,该属性的属性值指向当前实例所属类的原型

31.异步回调(如何解决回调地狱)

promise、generator、async/await

promise: 1.是一个对象,用来传递异步操作的信息。代表着某个未来才会知道结果的时间,并未这个事件提供统一的api,供进异步处理

  2.有了这个对象,就可以让异步操作以同步的操作的流程来表达出来,避免层层嵌套的回调地狱

  3.promise代表一个异步状态,有三个状态pending(进行中),Resolve(以完成),Reject(失败)

  4.一旦状态改变,就不会在变。任何时候都可以得到结果。从进行中变为以完成或者失败

promise.all() 里面状态都改变,那就会输出,得到一个数组

promise.race() 里面只有一个状态变为rejected或者fulfilled即输出

promis.finally()不管指定不管Promise对象最后状态如何,都会执行的操作(本质上还是then方法的特例)

32.前端事件流

事件流描述的是从页面中接受事件的顺序,事件 捕获阶段 处于目标阶段 事件冒泡阶段 addeventListener 最后这个布尔值参数如果是true,表示在捕获阶段调用事件处理程序;如果是false,表示在冒泡阶段调用事件处理程序。

  1、事件捕获阶段:实际目标div在捕获阶段不会接受事件,也就是在捕获阶段,事件从document到<html>再到<body>就停止了。

      2、处于目标阶段:事件在div发生并处理,但是事件处理会被看成是冒泡阶段的一部分。

      3、冒泡阶段:事件又传播回文档

  阻止冒泡事件event.stopPropagation()

  function stopBubble(e) {

    if (e && e.stopPropagation) { // 如果提供了事件对象event 这说明不是IE浏览器

      e.stopPropagation()

    } else {

      window.event.cancelBubble = true //IE方式阻止冒泡

          }

    }

  阻止默认行为event.preventDefault()

function stopDefault(e) {

    if (e && e.preventDefault) {

      e.preventDefault()

    } else {

      // IE浏览器阻止函数器默认动作的行为

      window.event.returnValue = false

    }

  }

33.事件如何先捕获后冒泡?

在DOM标准事件模型中,是先捕获后冒泡。但是如果要实现先冒泡后捕获的效果, 对于同一个事件,监听捕获和冒泡,分别对应相应的处理函数,监听到捕获事件,先暂缓执行,直到冒泡事件被捕获后再执行捕获事件。

哪些事件不支持冒泡事件:鼠标事件:mouserleave mouseenter 焦点事件:blur focus UI事件:scroll resize

34. 如何判断一个变量是对象还是数组(prototype.toString.call())。

千万不要使用typeof来判断对象和数组,因为这种类型都会返回object。

typeOf()是判断基本类型的Boolean,Number,symbol, undefined, String。 对于引用类型:除function,都返回object null返回object。

installOf() 用来判断A是否是B的实例,installof检查的是原型。

toString() 是Object的原型方法,对于 Object 对象,直接调用 toString() 就能返回 [Object Object] 。而对于其他对象,则需要通过 call / apply 来调用才能返回正确的类型信息。

hasOwnProperty()方法返回一个布尔值,指示对象自身属性中是否具有指定的属性,该方法会忽略掉那些从原型链上继承到的属性。

isProperty()方法测试一个对象是否存在另一个对象的原型链上。

35.setTimeout 和 setInterval的机制

因为js是单线程的。浏览器遇到etTimeout 和 setInterval会先执行完当前的代码块,在此之前会把定时器推入浏览器的

待执行时间队列里面,等到浏览器执行完当前代码之后会看下事件队列里有没有任务,有的话才执行定时器里的代码

36.splice和slice、map和forEach、 filter()、reduce()的区别

1.slice(start,end):方法可以从已有数组中返回选定的元素,返回一个新数组,

包含从start到end(不包含该元素)的数组方法

注意:该方法不会更新原数组,而是返回一个子数组

2.splice():该方法想或者从数组中添加或删除项目,返回被删除的项目。(该方法会改变原数组)

splice(index, howmany,item1,...itemx)

·index参数:必须,整数规定添加或删除的位置,使用负数,从数组尾部规定位置

·howmany参数:必须,要删除的数量,

·item1..itemx:可选,向数组添加新项目

3.map():会返回一个全新的数组。使用于改变数据值的时候。会分配内存存储空间数组并返回,forEach()不会返回数据

4.forEach(): 不会返回任何有价值的东西,并且不打算改变数据,单纯的只是想用数据做一些事情,他允许callback更改原始数组的元素

5.reduce(): 方法接收一个函数作为累加器,数组中的每一个值(从左到右)开始缩减,最终计算一个值,不会改变原数组的值

6.filter(): 方法创建一个新数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。它里面通过function去做处理

VUE问题

1.聊聊对vue的理解

vue是一个渐进式的JS框架。他易用,灵活,高效; 可以把一个页面分隔成多个组件;当其他页面有类似功能时,直接让封装的组件进行复用; 他是构建用户界面的声明式框架,只关心图层;不关心具体是如何实现的

2.V-model的原理是什么?

Vue的双向数据绑定是由数据劫持结合发布者订阅者实现的。 数据劫持是通过Object.defineProperty()来劫持对象数据的setter和getter操作。 在数据变动时作你想做的事

原理 通过Observer来监听自己的model数据变化,通过Compile来解析编译模板指令,最终利用Watcher搭起Observer和Compile之间的通信桥梁,达到数据变化->视图更新 在初始化vue实例时,遍历data这个对象,给每一个键值对利用Object.definedProperty对data的键值对新增get和set方法,利用了事件监听DOM的机制,让视图去改变数据

3.谈谈对生命周期的理解

beforeCreate阶段:vue实例的挂载元素el和数据对象data都是undefined,还没有初始化。

created阶段:vue实例的数据对象data有了,可以访问里面的数据和方法,未挂载到DOM,el还没有

beforeMount阶段:vue实例的el和data都初始化了,但是挂载之前为虚拟的dom节点

mounted阶段:vue实例挂载到真实DOM上,就可以通过DOM获取DOM节点

beforeUpdate阶段:响应式数据更新时调用,发生在虚拟DOM打补丁之前,适合在更新之前访问现有的DOM,比如手动移除已添加的事件监听器

updated阶段:虚拟DOM重新渲染和打补丁之后调用,组成新的DOM已经更新,避免在这个钩子函数中操作数据,防止死循环

beforeDestroy阶段:实例销毁前调用,实例还可以用,this能获取到实例,常用于销毁定时器,解绑事件

destroyed阶段:实例销毁后调用,调用后所有事件监听器会被移除,所有的子实例都会被销毁

4.VUE和REACT有什么区别?

react整体是函数式的思想,把组件设计成纯组件,状态和逻辑通过参数传入,所以在react中,是单向数据流;

vue的思想是响应式的,也就是基于是数据可变的,通过对每一个属性建立Watcher来监听,当属性变化的时候,响应式的更新对应的虚拟dom。

5.vuex的流程

页面通过mapAction异步提交事件到action。action通过commit把对应参数同步提交到mutation。

mutation会修改state中对于的值。 最后通过getter把对应值跑出去,在页面的计算属性中

通过mapGetter来动态获取state中的值

6.vuex有哪几种状态和属性

state中保存着共有数据,数据是响应式的

getter可以对state进行计算操作,主要用来过滤一些数据,可以在多组件之间复用

mutations定义的方法动态修改state中的数据,通过commit提交方法,方法必须是同步的

actions将mutations里面处理数据的方法变成异步的,就是异步操作数据,通store.dispatch来分发actions,把异步的方法写在actions中,通过commit提交mutations,进行修改数据。

modules:模块化vuex

7.vue路由的两种模式

hash ——即地址栏URL中的#符号(此hsah 不是密码学里的散列运算) hash 虽然出现URL中,但不会被包含在HTTP请求中,对后端完全没有影响,因此改变hash不会重新加载页面。

history ——利用了HTML5 History Interface 中新增的pushState() 和replaceState() 方法

这两个方法应用于浏览器的历史记录站,在当前已有的back、forward、go 的基础之上,它们提供了对历史记录进行修改的功能。只是当它们执行修改是,虽然改变了当前的URL,但你浏览器不会立即向后端发送请求。

8.vue中 key 值的作用

当 Vue.js 用v-for正在更新已渲染过的元素列表时,它默认用“就地复用”策略。 如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序,而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。

key的作用主要是为了高效的更新虚拟DOM。

9$route和$router的区别

$route是“路由信息对象”,包括path,params,hash,query,fullPath,matched,name等路由信息参数。

$router是“路由实例”对象包括了路由的跳转方法,钩子函数等。

10.vue-router守卫

导航守卫 router.beforeEach 全局前置守卫

to: Route: 即将要进入的目标(路由对象)

from: Route: 当前导航正要离开的路由

next: Function: 一定要调用该方法来 resolve 这个钩子。(一定要用这个函数才能去到下一个路由,如果不用就拦截) 执行效果依赖 next 方法的调用参数。

next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。

next(false): 取消进入路由,url地址重置为from路由地址(也就是将要离开的路由地址)。

// main.js 入口文件

    import router from './router'; // 引入路由

    router.beforeEach((to, from, next) => {

      next();

    });

    router.beforeResolve((to, from, next) => {

      next();

    });

    router.afterEach((to, from) => {

      console.log('afterEach 全局后置钩子');

    });

组件内的守卫 你可以在路由组件内直接定义以下路由导航守卫

const router = new VueRouter({

  routes: [

    {

      path: '/foo',

      component: Foo,

      beforeEnter: (to, from, next) => {

        // ...

      }

    }

  ]

})

组件内的守卫 你可以在路由组件内直接定义以下路由导航守卫

const Foo = {

  template: `...`,

  beforeRouteEnter (to, from, next) {

    // 在渲染该组件的对应路由被 confirm 前调用

    // 不!能!获取组件实例 `this`

    // 因为当守卫执行前,组件实例还没被创建

  },

  beforeRouteUpdate (to, from, next) {

    // 在当前路由改变,但是该组件被复用时调用

    // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,

    // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。

    // 可以访问组件实例 `this`

  },

  beforeRouteLeave (to, from, next) {

    // 导航离开该组件的对应路由时调用,我们用它来禁止用户离开

    // 可以访问组件实例 `this`

    // 比如还未保存草稿,或者在用户离开前,

    将setInterval销毁,防止离开之后,定时器还在调用。

  }

}

11.axios是什么?怎么使用?描述使用它实现登录功能的流程?

请求后台资源的模块。

$ npm install axios -S装好 复制代码

然后发送的是跨域,需在配置文件中config/index.js进行设置。后台如果是Tp5则定义一个资源路由。 js中使用import进来,然后.get或.post。返回在.then函数中如果成功,失败则是在.catch函数中

12.vue修饰符

stop:阻止事件的冒泡

prevent:阻止事件的默认行为

once:只触发一次

self:只触发自己的事件行为时,才会执行

13.vue项目中的性能优化

1.不要在模板里面写过多表达式

2.循环调用子组件时添加key

3.频繁切换的使用v-show,不频繁切换的使用v-if

4.尽量少用float,可以用flex

5.按需加载,可以用require或者import()按需加载需要的组件

6.路由懒加载

14.vue.extend和vue.component

extend 是构造一个组件的语法器。 然后这个组件你可以作用到Vue.component这个全局注册方法里 还可以在任意vue模板里使用组件。 也可以作用到vue实例或者某个组件中的components属性中并在内部使用apple组件。

Vue.component 你可以创建 ,也可以取组件。

常见的兼容问题

png24位的图片在iE6浏览器上出现背景 解决方案是做成PNG8.也可以引用一段脚本处理.

浏览器默认的margin和padding不同。 解决方案是加一个全局的*{margin:0;padding:0;}来统一。

IE6双边距bug:块属性标签float后,又有横行的margin情况下,在ie6显示margin比设置的大。

浮动ie产生的双倍距离(IE6双边距问题:在IE6下,如果对元素设置了浮动,同时又设置了margin-left或margin-right,margin值会加倍。) #box{ float:left; width:10px; margin:0 0 0 100px;}

React问题

1.react和vue的区别

=> 相同点:

1.数据驱动页面,提供响应式的试图组件

2.都有virtual DOM,组件化的开发,通过props参数进行父子之间组件传递数据,都实现了webComponents规范

3.数据流动单向,都支持服务器的渲染SSR

4.都有支持native的方法,react有React native, vue有wexx

=> 不同点:

1.数据绑定:Vue实现了双向的数据绑定,react数据流动是单向的

2.数据渲染:大规模的数据渲染,react更快

3.使用场景:React配合Redux架构适合大规模多人协作复杂项目,Vue适合小快的项目

4.开发风格:react推荐做法jsx + inline style把html和css都写在js了

vue是采用webpack + vue-loader单文件组件格式,html, js, css同一个文件

2.redux中的reducer(纯函数)

Redux数据流里,reduces其实是根据之前的状态(previous state)和现有的action(current action)

更新state(这个state可以理解为上下累加器的结果)

每次redux reducer被执行时,state和action被传入,这个state根据action进行累加或者是'自身消减'(reduce),

进而返回最新的state,这也就是典型reduce函数的用法:state ->  action ->  state

3.react的refs

refs就想一个逃生窗,允许我们之间访问dom元素或者组件实例,可以向组件添加一个ref属性的值是一个回调函数,

它将接受地城dom元素或组件的已挂在实例,作为第一个参数

4.react中的keys

帮组我们跟踪哪些项目已更改、添加、从列表中删除,key是独一无二的,可以让我们高效的去定位元素,并且操作它

5.React的生命周期

三个状态:Mounting(已插入真实的DOM)

  Updating(正在被重新渲染)

  Unmounting(已移除真实的DOM)

componentDIdMount 在第一次渲染后调用,只在客服端。之后组件已经生成对应的DOM结构,

componentDidUpdate 在组件完成更新后立即调用,在出初始化是不会调用

6.React子组件向父组件传值

父组件通过props 给子组件传递数据,子组件则是通过调用父组件传给它的函数给父组件传递数据。

7.为什么虚拟DOM会提高性能 www.zhihu.com/question/29…

虚拟DOM相当于在js和真实dom中间加了一个缓存,利用dom diff算法避免了没有必要的doom操作,从而提高性能

具体实现步骤:

·用JavaScript对象结构表示DOM树的结构;然后用这个树构建一个真正的DOM树,插到文档中

·当状态变更的时候,重新构造一棵树的对象树,然后用新的树和旧的树进行对比,记录两棵树差异

·把2所记录的差异应用到步骤1所构建的真正的DOM树上,试图就更新了。

8.diff算法

1.把树形结构按照层级分解,只比较同级元素

2.给列表结构的每个单元添加key属性,方便比较。在实际代码中,会对新旧两棵树进行一个深度优先的遍历,这样每个节点都会有一个标记

3.在深度优先遍历的时候,每遍历到一个节点就把该节点和新的树进行对比。如果有差异的话就记录到一个对象里面

Vritual DOM 算法主要实现上面步骤的三个函数:element, diff, patch。然后就可以实际的进行使用

react只会匹配相同的class的component(这里的class指的是组件的名字)

合并操作,条用component的setState方法的时候,React将其标记为dirty.到每一个时间循环借宿,React检查所有标记dirty的component重新绘制

4.选择性子树渲染。可以重写shouldComponentUpdate提高diff的性能

9.简述下flux的思想

flux的最大特点,就是数据的‘单向流动’ 1.用户访问View 2.View发出用户的Action 3.Dispatcher收到Action,要求state进行相应的更新 4.store更新后,发出一个‘change’事件后,更新页面

10.reac性能优化是哪个周期函

shouldComponentUpdate 这个方法用来判断是否需要调用render方法重新描绘dom.因为dom的描绘非常消耗性能, 如果我们在shouldComponentUpdate方法中能够写出更优化的dom diff算法,可以极大的提高性能

11.react怎么划分业务组件和技术组件

根据组件的职责通常把组件分为UI组件和容器组件 UI组件负责UI的呈现,容器组件负责管理数据和逻辑 两者通过React-redux提供connect方法联系起来

12.setState

setState通过一个队列机制实现state更新,当执行setState时,会将需要更新的state很后放入状态队列

而不会立即更新this.state,队列机制可以高效地批量更新state。如果不通过setState而直接修改this.state的值

那么该state将不会被放入状态队列中。当下次调用setState并对状态队列进行合并时,就会忽略之前修改的state,造成不可预知的错误

同时,也利用了队列机制实现了setState的异步更新,避免了频繁的重复更新state

同步更新state:

setState 函数并不会阻塞等待状态更新完毕,因此 setNetworkActivityIndicatorVisible 有可能先于数据渲染完毕就执行。

第二个参数是一个回调函数,在setState的异步操作结束并且组件已经重新渲染的时候执行

也就是说,我们可以通过这个回调来拿到更新的state的值,实现代码的同步

例子:componentDidMount() {

fetch('https://test.com')


.then((res) => res.json())


.then(

    (data) => {

this.setState({ data:data });

StatusBar.setNetworkActivityIndicatorVisible(false);

        }

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,311评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,339评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,671评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,252评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,253评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,031评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,340评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,973评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,466评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,937评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,039评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,701评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,254评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,259评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,485评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,497评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,786评论 2 345