金蝶云之家前端面经

2020年06月23日 阅读数:31
这篇文章主要向大家介绍金蝶云之家前端面经,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

目录javascript

 

一、vue router路由钩子css

完整的导航解析流程html

二、浏览器强弱缓存前端

强缓存vue

弱缓存java

三、v-show 是display:none // display opacity visibilitynode

四、简单请求和复杂请求webpack

五、http2ios

六、vuex能够直接更改state吗css3

七、权限路由

八、vue生命周期

九、双向绑定原理

十、实现跨域

十一、同源策略

十二、自适应和响应式的区别

1三、em和rem

1四、cookie不设置有效期多久过时

cookie的属性:

跨域解决方案

1五、浏览器存储方法 localstorage、sessionstorage、

1六、h5语义化优势

1七、get和post的区别

1八、懒加载原理实现方法

1九、前端如何让页面渲染更快

1、减小请求资源大小或者次数 

2、代码优化相关

20、dom事件流三个阶段,怎么阻止冒泡

2一、重绘回流

区别:

2二、display visibility opacity

2三、css水平垂直居中的方法

2四、清除浮动的方法

2五、css的两种盒模型

2六、深拷贝和浅拷贝的区别、怎么实现深拷贝

2七、js new的内部原理

3二、js事件循环

3三、宏任务和微任务有哪些

3四、闭包、闭包缺点

3五、call、apply、bind区别

3六、js 基本类型和引用类型有哪些、区别

3七、url到显示页面发生了什么

3八、http在哪层?七层协议

3九、经常使用http请求有哪些、get和post的区别

4二、es5模拟块级做用域(闭包)


一、vue router路由钩子

vue router路由钩子,导航守卫。vue-router 提供的导航守卫主要用来经过跳转或取消的方式守卫导航。

记住参数或查询的改变并不会触发进入/离开的导航守卫。你能够经过观察 $route 对象来应对这些变化,或使用 beforeRouteUpdate 的组件内守卫。

路由钩子函数有三种:

            1:全局钩子: beforeEach、 afterEach

            2:单个路由里面的钩子:  beforeEnter、 beforeLeave

            3:组件路由:beforeRouteEnter、 beforeRouteUpdate、 beforeRouteLeave

 

(1)全局前置守卫 router.beforeEach()

const router = new VueRouter({ ... })

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

当一个导航触发时,全局前置守卫按照建立顺序调用。守卫是异步解析执行,此时导航在全部守卫 resolve 完以前一直处于 等待中

每一个守卫方法接收三个参数:

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

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

  • next: Function: 必定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。

    • next(): 进行管道中的下一个钩子。若是所有钩子执行完了,则导航的状态就是 confirmed (确认的)。

    • next(false): 中断当前的导航。若是浏览器的 URL 改变了 (多是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。

    • next('/') 或者 next({ path: '/' }): 跳转到一个不一样的地址。当前的导航被中断,而后进行一个新的导航。你能够向 next 传递任意位置对象,且容许设置诸如 replace: truename: 'home' 之类的选项以及任何用在 router-linkto proprouter.push 中的选项。

    • next(error): (2.4.0+) 若是传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。

(2)全局解析守卫 router.beforeResolve

在 2.5.0+ 你能够用 router.beforeResolve 注册一个全局守卫。这和 router.beforeEach 相似,区别是在导航被确认以前,同时在全部组件内守卫和异步路由组件被解析以后,解析守卫就被调用。

 

(3)全局后置钩子 router.afterEach

你也能够注册全局后置钩子,然而和守卫不一样的是,这些钩子不会接受 next 函数也不会改变导航自己:这些守卫与全局前置守卫的方法参数是同样的。

 

(4)组件内的守卫

  • beforeRouteEnter
  • beforeRouteUpdate (2.2 新增)
  • beforeRouteLeave
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`
  }
}

 

 

完整的导航解析流程

  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 的回调函数。

 

二、浏览器强弱缓存

浏览器向服务器请求某一资源时,会先判断本地有无该资源缓存,若是已有缓存,则获取该资源缓存的 header 信息,根据 header 中的 Control 和 Expires (即强缓存)来判断是否过时。这一时刻是没有向服务器发出请求的。

若显示已过时,浏览器会向服务器发送请求,经过 header 中的 Etag 和 Last-Modified(协商缓存)让服务器验证。若不需更新资源,返回状态码 304;若须要更新,则返回最新资源和状态码 200
 

浏览器缓存主要分为强缓存(也称本地缓存)和协商缓存(也称弱缓存)。

强缓存

  http1.1 http1.0
强缓存

Cache-Control

强缓存利用的是max-age的值来实现缓存资源的最大生命周期,单位是秒。

Expires

它的值是一个绝对时间的GMT格式的时间字符串,表明资源失效时间。

协商缓存

Etag/If None Match

当资源被缓存时,服务器返回的 header 上有 Etag。

当资源文件向服务器确认缓存是否可用时,会向服务器发送一个 request header 带有 If-None-Match 字段,值为当前文件的 Etag。服务器根据浏览器上送的If-None-Match 值来判断是否命中缓存。

Last Modify/If Modify Since

浏览器第一次请求一个资源的时候,response header 会加上 Last-Modify,Last-modify 是一个时间标识该资源的最后修改时间。

当浏览器再次请求该资源时,request 的请求头中会包含 If-Modify-Since,该值为缓存以前返回的 Last-Modify。服务器收到If-Modify-Since 后,根据资源的最后修改时间判断是否命中缓存。
 

弱缓存

Last-Modify/If-Modify-Since

Last-Modify(实体首部)/If-Modify-Since(请求首部)是 http1.0 的规范,格式:Last-Modify: Fri, 19 Apr 2019 01:34:53 GMT

浏览器第一次请求一个资源的时候,response header 会加上 Last-Modify,Last-modify 是一个时间标识该资源的最后修改时间。

当浏览器再次请求该资源时,request 的请求头中会包含 If-Modify-Since,该值为缓存以前返回的 Last-Modify。服务器收到If-Modify-Since 后,根据资源的最后修改时间判断是否命中缓存。

若是命中缓存,返回304,则不会返回资源内容,而且不会返回 Last-Modify。

Etag和If-None-Match

Etag(响应首部)/If-None-Match(请求首部)是 http1.1 的规范,返回的是一个校验码,保证每个资源是惟一的,格式: Etag:22FAA065-2664-4197-9C5E-C92EA03D0A16。

当资源被缓存时,服务器返回的 header 上有 Etag。当资源文件向服务器确认缓存是否可用时,会向服务器发送一个 request header 带有 If-None-Match 字段,值为当前文件的 Etag。服务器根据浏览器上送的If-None-Match 值来判断是否命中缓存。

与 Last-Modified 不同的是,当命中缓存,服务器返回 304 Not Modified 的响应时,因为 ETag 从新生成过,response header 中还会把这个 ETag 返回,即便这个 ETag 跟以前的没有变化。

重点是,Etag 的优先级高于 Last-Modify,同时存在则优先判断 Etag,再判断 Last-Modify ,最后才决定是否返回304
 

 

三、v-show 是display:none // display opacity visibility

相同点:v-if与v-show均可以动态控制dom元素显示隐藏

不一样点:v-if显示隐藏是将dom元素整个添加或删除(好比div会被删掉),而v-show隐藏则是为该元素添加css--display:none,dom元素还在。

须要注意的是,当一个元素默认在css中加了display:none属性,这时经过if-show修改成true是没法让元素显示的。缘由是显示隐藏切换,只是会修改element style为display:""或者display:none,并不会覆盖掉或修改已存在的css属性。

详细区别:

1.手段:v-if是动态的向DOM树内添加或者删除DOM元素;v-show是经过设置DOM元素的display样式属性控制显隐;

2.编译过程:v-if切换有一个局部编译/卸载的过程,切换过程当中合适地销毁和重建内部的事件监听和子组件;v-show只是简单的基于css切换;

3.编译条件:v-if是惰性的,若是初始条件为假,则什么也不作;只有在条件第一次变为真时才开始局部编译(编译被缓存?编译被缓存后,而后再切换的时候进行局部卸载); v-show是在任何条件下(首次条件是否为真)都被编译,而后被缓存,并且DOM元素保留;

4.性能消耗:v-if有更高的切换消耗;v-show有更高的初始渲染消耗;

5.使用场景:v-if适合运营条件不大可能改变;v-show适合频繁切换。

 

1.display:none是完全消失,不在文档流中占位,浏览器也不会解析该元素;

visibility:hidden是视觉上消失了,能够理解为透明度为0的效果,在文档流中占位,浏览器会解析该元素;

2.使用visibility:hidden比display:none性能上要好,

display:none切换显示时,页面产生回流(当页面中的一部分元素须要改变规模尺寸、布局、显示隐藏等,页面从新构建,此时就是回流。全部页面第一次加载时须要产生一次回流),

而visibility切换是否显示时则不会引发回流。

3.opacity: 0 是透明度为0

具体来讲应该是: 

1 opacity=0,该元素隐藏起来了,但不会改变页面布局,而且,若是该元素已经绑定一些事件,如click事件,
那么点击该区域,也能触发点击事件的

2 visibility=hidden,该元素隐藏起来了,但不会改变页面布局,
可是不会触发该元素已经绑定的事件

3 display=none,把元素隐藏起来,而且会改变页面布局,能够理解成在页面中把该元素删除掉同样,可是dom元素还在

 

四、简单请求和复杂请求

跨域资源共享(简称cors,后面使用简称)来解决跨域问题。会用到的两种请求。

1. 简单请求:

知足一下两个条件的请求。

(1) 请求方法是如下三种方法之一:

  • HEAD
  • GET
  • POST

(2)HTTP的头信息不超出如下几种字段:

  • Accept
  • Accept-Language
  • Content-Language
  • Last-Event-I
  • D
  • Content-Type:只限于三个值application/x-www-form-urlencodedmultipart/form-datatext/plain

 

2. 复杂请求:

非简单请求就是复杂请求。

非简单请求是那种对服务器有特殊要求的请求,好比请求方法是PUTDELETE,或者Content-Type字段的类型是application/json

非简单请求的CORS请求,会在正式通讯以前,增长一次HTTP查询请求,称为"预检"请求(preflight)。

预检请求为OPTIONS请求,用于向服务器请求权限信息的。

预检请求被成功响应后,才会发出真实请求,携带真实数据。

axios 都是复杂请求,ajax 能够是简单请求

 

五、http2

HTTP2.0和HTTP1.X相比的新特性

  • 新的二进制格式(Binary Format),HTTP1.x的解析是基于文本。基于文本协议的格式解析存在自然缺陷,文本的表现形式有多样性,要作到健壮性考虑的场景必然不少,二进制则不一样,只认0和1的组合。基于这种考虑HTTP2.0的协议解析决定采用二进制格式,实现方便且健壮。

  • 多路复用(MultiPlexing),即链接共享,即每个request都是是用做链接共享机制的。一个request对应一个id,这样一个链接上能够有多个request,每一个链接的request能够随机的混杂在一块儿,接收方能够根据request的 id将request再归属到各自不一样的服务端请求里面。

  • header压缩,如上文中所言,对前面提到过HTTP1.x的header带有大量信息,并且每次都要重复发送,HTTP2.0使用encoder来减小须要传输的header大小,通信双方各自cache一份header fields表,既避免了重复header的传输,又减少了须要传输的大小。

  • 服务端推送(server push),同SPDY同样,HTTP2.0也具备server push功能。

 

六、vuex能够直接更改state吗

       不经过mutation,而直接修改state修改确实生效了。这样子多人协做岂不是很容易出问题。对于这个问题,在建立 store 的时候传入 strict: true, 开启严格模式,那么任何修改state的操做,只要不通过mutation的函数,vue就会 throw error。

七、权限路由

全局路由守卫拦截而后vuex存在localstorage里判断

八、vue生命周期

九、双向绑定原理

十、实现跨域

一、 经过jsonp跨域

一般为了减轻web服务器的负载,咱们把js、css,img等静态资源分离到另外一台独立域名的服务器上,在html页面中再经过相应的标签从不一样域名下加载静态资源,而被浏览器容许,基于此原理,咱们能够经过动态建立script,再请求一个带参网址实现跨域通讯。


二、 document.domain + iframe跨域

此方案仅限主域相同,子域不一样的跨域应用场景。

实现原理:两个页面都经过js强制设置document.domain为基础主域,就实现了同域。

(1)父窗口(http://www.demo.com/a.html)

<iframe id="iframe" src="http://child.demo.com/b.html"></iframe>
<script>
    document.domain = 'demo.com';
    var user = 'admin';
</script>

(2)子窗口:(http://child.demo.com/b.html)

<script>
    document.domain = 'demo.com';
    // 获取父窗口中变量
    alert('get js data from parent ---> ' + window.parent.user);
</script>

三、 location.hash + iframe
四、 window.name + iframe跨域
五、 postMessage跨域
六、 跨域资源共享(CORS)
七、 nginx代理跨域
八、 nodejs中间件代理跨域
九、 WebSocket协议跨域

十一、同源策略

  源是协议、域名和端口号。若地址里面的协议、域名和端口号均相同则属于同源。

       域名和对应的IP之间请求算跨域。

  同源策略是浏览器的一个安全功能,不一样源的客户端脚本在没有明确受权的状况下,不能读写对方资源。因此a.com下的js脚本采用ajax读取b.com里面的文件数据是会报错的。

  • 不受同源策略限制的
  1. 页面中的连接重定向以及表单提交是不会受到同源策略限制的。
  2. 跨域资源的引入是能够的。可是js不能读写加载的内容。如嵌入到页面中的<script src="..."></script>,<img>,<link>,<iframe>等。

      JavaScript只能访问和操做本身域下的资源,不能访问和操做其余域下的资源。跨域问题是针对JS和ajax的,html自己没有跨域问题,好比a标签、script标签、甚至form标签(能够直接跨域发送数据并接收数据)等。

同源策略限制如下几种行为:

一、Cookie、LocalStorage 和 IndexDB 没法读取
二、 DOM 和 Js对象没法得到
三、 AJAX 请求不能发送

 

十二、自适应和响应式的区别

1.什么是响应式布局

响应式布局就是实现不一样屏幕分辨率的终端上浏览网页的不一样展现方式。经过响应式设计能使网站在手机和平板电脑上有更好的浏览阅读体验。换句话说就是一个网站可以兼容多个终端,而不是为了每个终端作一个特定的版本。

2.什么是自适应式布局:

自适应布局就是指能忘了使网页自适应的显示在不一样大小终端设备上的新网页设计方式及技术,它须要开发多套界面来适应不一样的终端。

3.区别

(1)响应式布局经过检测视口分辨率,针对不一样客户端在客户端作代码处理,来展示不一样的布局和内容。

自适应布局经过检测视口分辨率,来判断当前访问的设备是:pc端、平板、手机,从而请求服务层,返回不一样的页面。

(2)自适应布局须要开发多套界面,而响应式布局只须要开发一套界面就能够了。

(3)自适应(媒体查询)对页面作的屏幕适配是在必定范围:好比pc端通常要大于1024像素,手机端要小于768像素。

而响应式布局是一套页面所有适应。

(4)自适应布局若是屏幕过小会发生内容过于拥挤。而响应式布局正是为了解决这个问题而衍生出的概念,它能够自动识别屏幕宽度并作出相应调整的网页设计。

总之,响应式布局仍是要比自适应布局要好一点,可是自适应布局更加贴切实际,由于你只须要考虑几种状态就能够了而不是像响应式布局须要考虑很是多状态。因此的说不管哪一种设计都有它们各自的特色,咱们要根据项目的需求来选择适合的布局方式。

自适应对差异大的更加友好,在某些范围内能够响应式。

 

1三、em和rem

在css中单位长度用的最多的是px、em、rem,这三个的区别是:

  px是固定的像素,一旦设置了就没法由于适应页面大小而改变。

  em和rem相对于px更具备灵活性,他们是相对长度单位,意思是长度不是定死了的,更适用于响应式布局。

       对于em和rem的区别一句话归纳:em相对于父元素,rem相对于根元素。

rem中的r意思是root(根源),这也就不难理解了。

em:

  • 子元素字体大小的em是相对于父元素字体大小(若是没有就是浏览器默认字体大小)
  • 元素的width/height/padding/margin用em的话是相对于该元素的font-size

浏览器字体大小有两个须要注意的地方,有时候会碰到兼容性的问题。
第一,是浏览器默认的字体大小是16px,因此重置css的时候将字体大小默认改成10px是这样改的:

html,body {font-size: 62.5%;}

后面设置字体大小rem,em都依据body的字体大小计算比较方便。

 

第2、chrome的字体最小为12px 设置成10px 显示仍是12px

顺便解决chrome字体最小为12px的方法用css3

     .small-font{
            font-size: 12px;
            -webkit-transform-origin-x: 0;
            -webkit-transform: scale(0.90);

        }

  利用css3的缩放,其最终大小就是:12px * 0.9(缩放比例) = 10.8px;

  竟然行得通。但回头一想,这么写的话,IE7 IE8会不会不兼容,仍是12px呢?不出所料,果真不兼容。此时,又回头一想,要再也不加个样式font-size?试了一下,果真兼容谷歌,IE7,IE8,代码以下:

         .small-font{    

     font-size:12px; 
            -webkit-transform-origin-x: 0;
            -webkit-transform: scale(0.90);
        }


        .smallsize-font {
     font-size:10.8px;

        }

  <p style="color: #FF0000;" class="small-font smallsize-font">舒适提示:</p>

 

1四、cookie不设置有效期多久过时

 

设置Cookie的失效时间:

若是Cookie没有设置expires属性(默认-1?),那么 cookie 的生命周期只是在当前的会话中,

关闭浏览器意味着此次会话的结束,此时 cookie 随之失效。

cookie.Expires   =   DataTime.MaxValue   ;//永不过时

cookie的属性:

name字段为一个cookie的名称。

value字段为一个cookie的值。

domain字段为能够访问此cookie的域名。没法设置除当前域名或者其父域名以外的其余domain,

如在www.wo.cao.baidu.com  域名下只能设置 cao.baidu.com,baidu.com

不能设置 da.jia.wo.cao.baidu.com的cookie。

domain属性可使多个web服务器共享cookie。domain属性的默认值是建立cookie的网页所在服务器的主机名。不能将一个cookie的域设置成服务器所在的域以外的域。
例如让位于order.example.com的服务器可以读取catalog.example.com设置的cookie值。若是 catalog.example.com的页面建立的cookie把本身的path属性设置为“/”,把domain属性设置成 “.example.com”,那么全部位于catalog.example.com的网页和全部位于orlders.example.com的网页,以 及位于example.com域的其余服务器上的网页均可以访问这个cookie。

跨域解决方案

一、 经过jsonp跨域
二、 document.domain + iframe跨域
三、 location.hash + iframe
四、 window.name + iframe跨域
五、 postMessage跨域
六、 跨域资源共享(CORS)
七、 nginx代理跨域
八、 nodejs中间件代理跨域
九、 WebSocket协议跨域

path字段为能够访问此cookie的页面路径。 好比domain是abc.com,path是/test,那么只有/test路径下的页面能够读取此cookie。

expires/Max-Age 字段为此cookie超时时间。若设置其值为一个时间,那么当到达此时间后,此cookie失效。不设置的话默认值是Session,意思是cookie会和session一块儿失效。当浏览器关闭(不是浏览器标签页,而是整个浏览器) 后,此cookie失效。

Expires指定一个绝对的过时时间(GMT格式),这么作会致使至少2个问题:(绝对时间)
1)客户端和服务器时间不一样步致使Expires的配置出现问题;
2)很容易在配置后忘记具体的过时时间,致使过时来临出现浪涌现象;

max-age 指定的是从文档被访问后的存活时间(秒),这个时间是个相对值(好比:3600s),相对的是文档第一次被请求时服务器记录的Request_time(请求时间)(相对时间)

 

Size字段 此cookie大小。(4kb)

http字段  cookie的httponly属性。若此属性为true,则只有在http请求头中会带有此cookie的信息,而不能经过document.cookie来访问此cookie。

那么经过js脚本将没法读取到cookie信息,这样能有效的防止XSS攻击,窃取cookie内容,这样就增长了cookie的安全性。

secure 字段 设置是否只能经过https协议来传递此条cookie


 

1五、浏览器存储方法 localstorage、sessionstorage、

1六、h5语义化优势

语义化优势:

  • 易于用户阅读,样式丢失的时候能让页面呈现清晰的结构
  • 有利于SEO,搜索引擎根据标签来肯定上下文和各个关键字的权重
  • (seo:利用搜索引擎的规则提升网站在有关搜索引擎内的天然排名
  • 方便其余设备解析,如盲人阅读器根据语义渲染网页
  • 有利于开发和维护,语义化更具可读性,代码更好维护,与CSS3关系更和谐。

 

1七、get和post的区别

get参数经过url传递,post放在request body中。

get请求在url中传递的参数是有长度限制的,而post没有。

get比post更不安全,由于参数直接暴露在url中,因此不能用来传递敏感信息。

get请求只能进行url编码,而post支持多种编码方式

get请求会浏览器主动cache,而post支持多种编码方式。

get请求参数会被完整保留在浏览历史记录里,而post中的参数不会被保留。

GET和POST本质上就是TCP连接,并没有差异。可是因为HTTP的规定和浏览器/服务器的限制,致使他们在应用过程当中体现出一些不一样。

GET产生一个TCP数据包;POST产生两个TCP数据包。

 

1八、懒加载原理实现方法

1九、前端如何让页面渲染更快

1、减小请求资源大小或者次数 

一、尽可能和并和压缩css和js文件。(将css文件和并为一个。将js合并为一个)
  缘由:主要是为了减小http请求次数以及减小请求资源的大小
  打包工具:
  webpack
  gulp
  grunt
.  ....
二、尽可能所使用的字体图标或者SVG图标来代替传统png图
  由于字体图标或者SVG是矢量图,代码编写出来的,方大不会变形,并且渲染速度快

三、采用图片的懒加载(延迟加载)
  目的为了,减小页面第一次加载过程当中http的请求次数
  具体步骤:
    一、页面开始加载时不去发送http请求,而是放置一张占位图
    二、当页面加载完时,而且图片在可视区域再去请求加载图片信息

四、能用css作的效果,不要用js作,能用原生js作的,不要轻易去使用第三方插件。
  避免引入第三方大量的库。而本身却只是用里面的一个小功能

五、使用雪碧图或者是说图片精灵
  把全部相对较小的资源图片,绘制在一张大图上,只须要将大图下载下来,而后利用
  图片定位来说小图展示在页面中(background-position:百分比,数值)

六、减小对cookie的使用(最主要的就是减小本地cookie存储内容的大小),由于客户端操做cookie的时候,这些信息老是在客户端和服务端传递。若是上设置不当,每次发送

一个请求将会携带cookie

七、前端与后端进行数据交互时,对于多项数据尽量基于json格式来进行传送。相对于使用xml
  来讲传输有这个优点
  目的:是数据处理方便,资源偏小

八、前端与后端协商,合理使用keep-alive

九、前端与服务器协商,使用响应资源的压缩

十、避免使用iframe
  不只很差管控样式,并且至关于在本页面又嵌套其余页面,消耗性能会更大。由于还回去加载这个嵌套页面的资源

十一、在基于ajax的get请求进行数据交互的时候,根据需求可让其产生缓存(注意:这个
缓存不是咱们常看到的304状态码,去浏览器本地取数据),这样在下一次从相同地址获取是数据
时,取得就是上一次缓存的数据。(注意:不多使用,通常都会清空。根据需求来作)

2、代码优化相关

一、在js中尽可能减小闭包的使用
  缘由:使用闭包后,闭包所在的上下文不会被释放

二、减小对DOM操做,主要是减小DOM的重绘与回流(重排)
  关于重排(回流)的分离读写:若是须要设置多个样式,把设置样式全放在一块儿设置,不要一条一条的设置。使用文档碎片或者字符串拼接作数据绑定(DOM的动态建立)

三、在js中避免嵌套循环和"死循环"(一旦遇到死循环,浏览器就会直接卡掉)

四、把css放在body上,把js放在body下面
  让其先加载css(注意:这里关于优化没有多大关系)

五、减小css表达式的使用

六、css选择器解析规则所示从右往左解析的。减小元素标签做为对后一个选择对象

七、尽可能将一个动画元素单独设置为一个图层(避免重绘或者回流的大小)
  注意:图层不要过多设置,不然不但效果没有达到反而更差了

八、在js封装过程当中,尽可能作到低耦合高内聚。减小页面的冗余代码

九、css中设置定位后,最好使用z-index改变盒子的层级,让盒子不在相同的平面上

十、css导入的时候尽可能减小@import导入式,由于@import是同步操做,只有把对应的样式导入后,才会继续向下加兹安,而link是异步的操做

十一、使用window.requestAnimationFrame(js的帧动画)代替传统的定时器动画
  若是想使用每隔一段时间执行动画,应该避免使用setInterval,尽可能使用setTimeout
  代替setInterval定时器。由于setInterval定时器存在弊端:可能形成两个动画间隔时间
  缩短

十二、尽可能减小使用递归。避免死递归
  解决:建议使用尾递归

1三、基于script标签下载js文件时,可使用defer或者async来异步加载

1四、在事件绑定中,尽量使用事件委托,减小循环给DOM元素绑定事件处理函数。

1五、在js封装过程当中,尽可能作到低耦合高内聚。减小页面的冗余代码

1六、减小Flash的使用

3、存储

一、结合后端,利用浏览器的缓存技术,作一些缓存(让后端返回304,告诉浏览器去本地拉取数据)。(注意:也有弊端)可让一些不太会改变的静态资源作缓存。好比:一些图片,js,cs

二、利用h5的新特性(localStorage、sessionStorage)作一些简单数据的存储,
  避免向后台请求数据或者说在离线状态下作一些数据展现。

4、其余优化

一、避免使用iframe不只很差管控样式,并且至关于在本页面又嵌套其余页面,消耗性能会更大。由于还回去加载这个嵌套页面的资源

二、页面中的是数据获取采用异步编程和延迟分批加载,使用异步加载是数据主要是为了不浏览器失去响应。若是你使用同步,加载数据很大而且很慢
  那么,页面会在一段时间内处于阻塞状态。目的:为了解决请求数据不耽搁渲染,提升页面的
  渲染效率。解决方法:须要动态绑定的是数据区域先隐藏,等数据返回而且绑定后在让其显示
  延迟分批加载相似图片懒加载。减小第一次页面加载时候的http请求次数

三、页面中出现音视频标签,咱们不让页面加载的时候去加载这些资源(不然第一次加载会很慢)
  解决方法:只须要将音视频的preload=none便可。
  目的:为了等待页面加载完成时,而且音视频要播放的时候去加兹安音视频资源

四、尽可能将一个动画元素单独设置为一个图层(避免重绘或者回流的大小)
  注意:图层不要过多设置,不然不但效果没有达到反而更差了

 

20、dom事件流三个阶段,怎么阻止冒泡

事件流描述的是从页面接收事件的顺序。

IE提出是事件流是事件冒泡流,Netscape Communicator提出的是事件捕获流。

IE事件冒泡流:

点击了div那么

div-> body -> html -> document(ie九、firefox、chrome、safari会冒泡至window)

事件捕获则相反。在事件到达预约目标以前捕获他。

 

dom2级事件规定的事件流包括三个阶段:

事件捕获阶段、处于目标阶段、事件冒泡阶段。

 

事件冒泡过程,是能够被阻止的。防止事件冒泡而带来没必要要的错误和困扰。
这个方法就是:stopPropagation()

阻止事件冒泡:w3c的方法是e.stopPropagation(),IE则是使用e.cancelBubble = true

取消默认事件:w3c的方法是e.preventDefault(),IE则是使用e.returnValue = false;

原生js取消事件冒泡

    try{
        e.stopPropagation();//非IE浏览器
    }
    catch(e){
        window.event.cancelBubble = true;//IE浏览器
    }    

原生js阻止默认事件

if ( e && e.preventDefault ) {
            e.preventDefault()//非IE浏览器
} else { window.event.returnValue = false; } //IE浏览器

 

vue.js取消事件冒泡

<div @click.stop="doSomething($event)">vue取消事件冒泡</div>

vue.js阻止默认事件

<div @click.prevent="doSomething($event)">vue阻止默认事件</div>

在Vue中,因为事件捕获和冒泡的存在,当点击某个元素时会引起其父元素(父父元素、父父父元素…)的点击事件发生,使得点击某个元素时达不到想要的效果。.self修饰符能够很好的解决这一状况,.self修饰符只有在点击事件绑定的元素当前被点击元素一致时才触发点击事件。

.stop 是阻止冒泡行为,不让当前元素的事件继续往外触发,如阻止点击div内部事件,触发div事件
.prevent 是阻止事件自己行为,如阻止超连接的点击跳转,form表单的点击提交
.self 是只有是本身触发的本身才会执行,若是接受到内部的冒泡事件传递信号触发,会忽略掉这个信号
.capture 是改变js默认的事件机制,默认是冒泡,capture功能是将冒泡改成倾听模式
.once 是将事件设置为只执行一次,如 .click.prevent.once 表明只阻止事件的默认行为一次,当第二次触发的时候事件自己的行为会执行

.self和.stop区别: .self只是阻止自身不执行冒泡触发,不会阻止冒泡继续向外部触发,.stop是从自身开始不向外部发射冒泡信号

 

2一、重绘回流

区别:

他们的区别很大:
回流必将引发重绘,而重绘不必定会引发回流。好比:只有颜色改变的时候就只会发生重绘而不会引发回流
当页面布局和几何属性改变时就须要回流
好比:添加或者删除可见的DOM元素,元素位置改变,元素尺寸改变——边距、填充、边框、宽度和高度,内容改变

 

2二、display visibility opacity

2三、css水平垂直居中的方法

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

或者

margin:auto; postion:absolute; left/right/top/bottom:0;

2四、清除浮动的方法

父元素overflow:hidden

父元素::after{

   content:"";clear:both;display:block;

}

子元素后加兄弟div clear:both

1.额外标签法(在最后一个浮动标签后,新加一个标签,给其设置clear:both;)(不推荐)

2.父级添加overflow属性(父元素添加overflow:hidden)(不推荐)

3.使用after伪元素清除浮动(推荐使用)

4.使用before和after双伪元素清除浮动

 

2五、css的两种盒模型

标准盒模型:box-sizing:content-box   content的宽高为宽高

IE盒模型:box-sizing:border-box        content padding border一块儿的宽高为宽高

 

2六、深拷贝和浅拷贝的区别、怎么实现深拷贝

浅拷贝与深拷贝

1、数据类型
数据分为基本数据类型(String, Number, Boolean, Null, Undefined,Symbol)和对象数据类型。

基本数据类型的特色:直接存储在栈(stack)中的数据
引用数据类型的特色:存储的是该对象在栈中引用,真实的数据存放在堆内存里

引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中得到实体。

浅拷贝只复制指向某个对象的指针,而不复制对象自己,新旧对象仍是共享同一块内存但深拷贝会另外创造一个如出一辙的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。

5、深拷贝的实现方式

  1. JSON.parse(JSON.stringify())
    //数组非函数
  2. 手写递归方法  递归方法实现深度克隆原理:遍历对象、数组直到里边都是基本数据类型,而后再去复制,就是深度拷贝
  3. 函数库lodash  _.cloneDeep
  4. a.concat()
  • 第一级是深拷贝,之后各级是浅拷贝
  • B复制A —— A变B变,浅拷贝 ;A变B不变,深拷贝
 

第一级是深拷贝:

let a = {James: {age: 18}}

let b = Object.assign({}, a)

b.James = 20

console.log(b) // { James: 20 }

console.log(a) // { James: { age: 18 } }

 

之后各级是浅拷贝:

let a = {James: {age: 18}}

let b = Object.assign({}, a)

b.James.age = 20

console.log(b) // { James: { age: 20 } }

console.log(a) // { James: { age: 20 } }

 

2七、js new的内部原理

2八、箭头函数和普通函数的区别

 

2九、怎么不用const和let实现块级做用域

30、let、const、var

3一、es6新特性

3二、js事件循环

3三、宏任务和微任务有哪些

宏队列,macrotask,也叫tasks。 一些异步任务的回调会依次进入macro task queue,等待后续被调用,这些异步任务包括:

  • setTimeout
  • setInterval
  • setImmediate (Node独有)
  • requestAnimationFrame (浏览器独有)
  • I/O
  • UI rendering (浏览器独有)

微队列,microtask,也叫jobs。 另外一些异步任务的回调会依次进入micro task queue,等待后续被调用,这些异步任务包括:

  • process.nextTick (Node独有)
  • Promise
  • Object.observe
  • MutationObserver
  • async await

 

3四、闭包、闭包缺点

闭包就是可以读取其余函数内部变量的函数。

闭包能够用在许多地方。它的最大用处有两个,一个是前面提到的能够读取函数内部的变量,另外一个就是让这些变量的值始终保持在内存中,不会在f1调用后被自动清除。

为何会这样呢?缘由就在于f1是f2的父函数,而f2被赋给了一个全局变量,这致使f2始终在内存中,而f2的存在依赖于f1,所以f1也始终在内存中,不会在调用结束后,被垃圾回收机制(garbage collection)回收。

(1)因为闭包会携带包含它的函数的做用域链,比其余函数消耗更多的内存,过分使用,内存消耗很大,因此不能滥用闭包,不然会形成网页的性能问题,在IE中可能致使内存泄露。解决方法是,在退出函数以前,将不使用的局部变量所有删除。解除对匿名函数的引用。

(2)做用域链这种配置做用的反作用是,闭包只能取得包含函数中任何变量的最后一个值。闭包保存的是整个变量对象,不是某个特殊的变量。每一个做用域链中都保存着外层函数的活动对象,他们引用的也都是里面同一个变量,而不是几个不一样的变量副本。好比for循环后,只保存了一个i。

(3)匿名函数的执行具备全局性,this对象一般指向window。每一个匿名函数被调用自动获取两个值this和arguments。内部函数在搜索这两个变量,只会搜索到其活动对象为止,所以永远不会直接访问外部函数中的这两个值。除非用var that = this保存起来再访问。arguments也是同理。

(4)内存泄漏

IE9以前对Jscript对象和COM对象使用不一样的垃圾收集例程。闭包在这些版本会致使一些特殊问题。好比若是闭包内保存着一个html元素,那么意味着该元素将没法被销毁,占用的内存永远不会被回收。

function assignHandler(){
    var element = document.getElementById("someElement");
    element.onclick() = function(){
        alert(element.id)
    }
}

解决办法:

function assignHandler(){
    var element = document.getElementById("someElement");
    var id = element.id;
    element.onclick() = function(){
        alert(id)
    }
    element = null;
}

把element.id保存在变量中,消除循环引用。把element设置成null,消除对DOM对象的引用。

 

3五、call、apply、bind区别

在JS中,这三者都是用来改变函数的this对象的指向的,他们有什么样的区别呢。
在说区别以前仍是先总结一下三者的类似之处:
一、都是用来改变函数的this对象的指向的。
二、第一个参数都是this要指向的对象。
三、均可以利用后续参数传参。

call调用 将方法中的this指向call中第一个参数,当第一个参数为null、undefined时,默认指向window; call中第一个参数以后是要传递给方法的参数列表。

call(obj, a1, a2, a3)

apply与call类似,不一样之处在于传递给方法的参数形式不一致。apply传递给方法的参数是数组的形式。

apply(obj, [a1, a2, a3])

bind 方法 与 apply 和 call 比较相似,也能改变函数体内的 this 指向。不一样的是,bind 方法的返回值是函数,而且须要稍后调用,才会执行。而 apply 和 call 则是当即调用。

bind(obj, a1, a2, a3)()

 

3六、js 基本类型和引用类型有哪些、区别

 

3七、url到显示页面发生了什么

基本面试必问了,有空出个专门的blog好好总结一下最全面的an

 

3八、http在哪层?七层协议

应用层

物理层-数据链路层-网络层-传输层-会话层-表示层-应用层

 

3九、经常使用http请求有哪些、get和post的区别

序号 方法 描述
1 GET

发送请求来得到服务器上的资源,请求体中不会包含请求数据,请求数据放在协议头中。另外get支持快取、缓存

、可保留书签等。幂等

2 POST

和get同样很常见,向服务器提交资源让服务器处理,好比提交表单、上传文件等,可能致使创建新的资源或者对

原有资源的修改。提交的资源放在请求体中。不支持快取。非幂等

3 HEAD

本质和get同样,可是响应中没有呈现数据,而是http的头信息,主要用来检查资源或超连接的有效性或是否能够可达、检

查网页是否被串改或更新,获取头信息等,特别适用在有限的速度和带宽下。

4 PUT

和post相似,html表单不支持,发送资源与服务器,并存储在服务器指定位置,要求客户端事先知

道该位置;好比post是在一个集合上(/province),而put是具体某一个资源上(/province/123)。因此put是安全的,

不管请求多少次,都是在123上更改,而post可能请求几回建立了几回资源。幂等

5 DELETE 请求服务器删除某资源。和put都具备破坏性,可能被防火墙拦截。若是是https协议,则无需担忧。幂等
6 CONNECT

HTTP/1.1协议中预留给可以将链接改成管道方式的代理服务器。就是把服务器做为跳板,去访问其余网页

而后把数据返回回来,链接成功后,就能够正常的get、post了。

7 OPTIONS 获取http服务器支持的http请求方法,容许客户端查看服务器的性能,好比ajax跨域时的预检等。
8 TRACE

回显服务器收到的请求,主要用于测试或诊断。通常禁用,防止被恶意攻击或盗取信息。

、项目中的难题

4一、事件代理

 

4二、es5模拟块级做用域(闭包)

使用IFE当即执行函数造成闭包

(function(){

   //块级做用域

})();

用当即执行函数包裹for循环,状况就不同了:
 

function outputNumbers(count){

    (function(){

        for(var i = 0; i < count; ++i){

        console.log(i);

    }})();

    console.log(i);//Uncaught ReferenceError: i is not defined

}

outputNumbers(5);

//结果 0 1 2 3 4

此时i绑定在内部当即执行函数的变量对象上,当即执行函数执行完毕就会销毁,i也会随之销毁,变量不会在外部还能使用。

根据闭包机制,内部的当即执行函数也能够访问到count。这样就实现了块级做用域——不管在当即执行函数中声明什么变量都不会影响外部变量的使用。