首页IT科技2021年前端面试(2023年前端面试题汇总)

2021年前端面试(2023年前端面试题汇总)

时间2025-07-31 21:35:38分类IT科技浏览5070
导读:一:JavaScript 1、闭包是什么?利弊?如何解决弊端?...

一:JavaScript 

1               、闭包是什么?利弊?如何解决弊端?

闭包是什么:JS中内层函数可以访问外层函数的变量               ,外层函数无法操作内存函数的变量的特性            。我们把这个特性称作闭包                     。

闭包的好处

隔离作用域                  ,保护私有变量;有了闭包才有局部变量      ,要不然都是全局变量了      。 让我们可以使用回调            ,操作其他函数内部; 变量长期驻扎在内存中                   ,不会被内存回收机制回收         ,即延长变量的生命周期;

闭包的弊端:内层函数引用外层函数变量        ,内层函数占用内存         。如果不释放内存                    ,过多时            ,易引起内存泄露                     。

解决办法:无法自动销户    ,就及时手动回收                     ,使用后将函数的引用赋null          。

2                  、深度拷贝

1      、深拷贝与浅拷贝的区别?

拷贝的层级不同               ,深拷贝是指每一层数据的改动都不会影响原对象和新对象,浅拷贝只有第一层的属性变动不互相影响                  ,深层的数据变动还会互相影响      。

浅拷贝:Object.assign 深拷贝:JSON.stringify和JSON.parse

2            、JSON的stringify和parse处理的缺点?

如果对象中有属性是function或者undefined                  ,处理后会被过滤掉; 如果属性值是对象   ,且由构造函数生成的实例对象               ,会丢弃对象的constructor;

3                   、$.extend()

使用jquey的extend方法不仅能实现深度拷贝                  ,还能实现深度合并                    。具体用法

深度拷贝:$.extend({},targetObject) // targetObject是需要复制的对象

深度合并:$.extend(true,{},targetObject1,targetObject2) // 可以将两个对象深度合并后再返回出一个新对象

3         、如何判断空对象?如何区分数据类型?

    判断空对象

1        、用JSON的stringify和parse转成字符串后      ,跟{}对比; 2                    、用ES6            ,判断Object.keys(targetObject)返回值数组的长度是否为0; 3            、用ES5                   ,判断Object.getOwnPropertyNames(targetObject)返回的数组长度是否为0;

   区分数据类型

let a = [1,2] Object.prototype.toString.call(a) // [object Array]

4    、如何改变this指向?区别?

call/apply let a = { name: sunq, fn:function(action){ console.log(this.name + love + action); } } let b = {name:sunLi} // 正常的this指向 a.fn(basketball); // sunq love basketball // 改变this指向         ,并体现call与apply的区别 a.fn.apply(b,[football]); // sunLi love football a.fn.call(b,football); // sunLi love football // call 和 apply 区别: call 和 apply 都是可以改变this 指向的问题, call 方法中传递参数要求一 // 个 一个传递参数              。 但是apply 方法要求传递参数是一个数组形式   。 bind // 还是上面的示例        ,bind也可以实现call和apply的效果                   。 // bind的不同之处在于bind会返回一个新的函数                  。如果需要传参                    ,需要再调用该函数并传参 a.fn.bind(b)(piano); // sunLi love piano

5                     、沙箱隔离怎么做?

使用iframe可以实现            ,变量隔离

6               、浏览器存储    ,他们的区别?

localStorage:永久保存                     ,以键值对保存               ,存储空间5M sessionStorage:关闭页签/浏览器时清空 cookie:随着请求发送,通过设置过期时间删除 session:保存在服务端

localStorage/sessionStorage是window的属性                  ,cookie是document的方法

7、常用的数组方法有哪些?

改变原数组:push                  、pop                  、shift   、unshift               、sort                  、splice      、reverse 不改变原属组:concat            、join                   、map         、forEach        、filter                    、slice

    slice和splice的区别?

slice切片的意思                  ,根据传入的起始和终止下标   ,获取该范围数组。 splice可根据传入参数个数不同实现删除            、插入操作               ,直接操作原数组               。第1个参数为起始下标                  ,第2个为删除个数      ,第3个为要增加的数据                     。

数组如何滤重?

8    、Dom事件流的顺序?什么是事件委托?

当页面上的一个元素被点击时            ,先从document向下一层层捕获到该元素   。然后再向上冒泡                   ,一层层触发            。

事件委托是将事件写在父级元素上         ,e.target是事件捕获时那个最小的元素        ,即选中的元素                     。所以可以根据e.target操作选中的元素      。这样不需要给每个子元素绑定事件                    ,代码更加简约         。

9                     、对原型链的认识?

js通过原型链模拟实现面向对象            ,比如通过实例化一个构造函数可以给每个对象挂载自己专属的属性    ,通过给类的prototype上赋方法是所有对象所共有的方法                     。每次实例化不再赋值原型链上的方法          。

10               、防抖/节流的区别?

区别:防抖只会在最后一次事件后执行触发函数                     ,节流不管事件多么的频繁               ,都会保证在规定时间段内触发事件函数      。

防抖:

原理是维护一个定时器,将很多个相同的操作合并成一个                    。规定在delay后触发函数                  ,如果在此之前触发函数                  ,则取消之前的计时重新计时   ,只有最后一次操作能被触发              。例如:实时搜索的input               ,一直输入就不发送   。

let input = document.querySelector("input"); let time = null;//time用来控制事件的触发 input.addEventListener(input,function(){ //防抖语句                  ,把以前的定时删除      ,只执行最后一次 if(time !== null){ clearTimeout(time); } time = setTimeout(() => { console.log(this.value);//业务实现语句            ,这里的this指向的是input },500) }) 节流:

原理是判断是否达到一定的时间来触发事件                   。某个时间段内只能触发一次函数                  。例如:在指定的时间内多次触发无效

//节流 function throttle(fn, time) {//连续触发事件 规定的时间 let flag = false; return function () { //使用标识判断是否在规定的时间内重复触发了函数                   ,没有就触发         ,有就不触发 if (!flag) {//不为假时 执行以下 fn();//触发事件 flag = true;//为真 setTimeout(() => {//超时调用(在规定的时间内只执行一次) flag = false; }, time); } } } mybtn.onclick = throttle(btn, 3000);//单击事件 节流(btn,3s时间)

二:Html

1、重绘和重排(回流/重构/重载)是什么?如何优化?

样式的调整会引起重绘        ,比如字体颜色                  、背景色调整等 Dom的变动会引起重排                    ,比如定位改动                  、元素宽高调整

避免循环插入dom            ,比如table的行。可以js循环生成多个dom后    ,一次性插入               。

2   、html5有哪些新特性?

本地存储                     ,比如localStorage               、sessionStorage 语义化标签               ,如header                  、footer      、nav等,使代码结构清晰                  ,利于seo canvas svg web worker                  ,在主线程外再创建一个线程   ,可与主线程交互 拖放功能

三:CSS

1            、如何实现一个宽度不固定的上下左右居中的弹框?

方法一: .pop{ width: 300px; height: 300px; position: fixed; left: 0; right: 0; top: 0; bottom: 0; margin: auto; border: 1px solid red; } 方法二: .chartLengend { // 父元素 width: 60px; height: 40px; position: relative; .line { // 子元素 width: 100%; height: 3px; background-color: #DEA182; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); border-radius: 2px; } }

2                   、伪类和伪元素区别?

伪类本质上用于弥补常规css选择器的不足               ,因为如果没有我们可能需要多写一个class                  ,所以叫伪类 .class:last-child{} .class:first-child{} a:link {color:green;} a:visited {color:green;} a:hover {color:red;} a:active {color:yellow;} 伪元素本质上是创建了一个有内容的虚拟元素      ,如::before   ::after                     。因为相当于多了一个元素/节点            ,所以叫为元素 // :before用于在某个元素之前插入某些内容   。 // :after用于在某个元素之后插入某些内容            。 css p:before{ content:"Read this: "; } html: <p>I live in Ducksburg</p> 页面展示: Read this: I live in Ducksburg F12看dom中: before Read this: I live in Ducksburg

四:Vue

1         、单页面应用是什么?优缺点?如何弥补缺点

单页面对一个入口DOM通过路由去更改内容                   ,整个应用只有一个html页面

SPA优点:用户体验好         ,没有页面切换就没有白屏情况;

SPA缺点:首屏加载慢        ,不利于SEO

SPA弥补:通过压缩        、路由懒加载缓解首屏慢;通过SSR 服务器端渲染解决SEO问题;

2                    、组件及通信方式有哪些?

2.1            、什么是组件?

组件是可复用的 Vue 实例                    ,且带有一个名字:在这个例子中是                      。我们可以在一个通过 new Vue 创建的 Vue 根实例中            ,把这个组件作为自定义元素来使用:

声明组件

// 定义一个名为 button-counter 的新组件 Vue.component(button-counter, { data: function () { return { count: 0 } }, template: <button v-on:click="count++">You clicked me {{ count }} times.</button> })

使用组件(把组件当作自定义元素)

<div id="components-demo"> <button-counter></button-counter> </div>

引入组件

new Vue({ el: #components-demo })

2.2    、父向子传值

Prop 是你可以在组件上注册的一些自定义 attribute      。当一个值传递给一个 prop attribute 的时候    ,它就变成了那个组件实例的一个 property         。为了给博文组件传递一个标题                     ,我们可以用一个 props 选项将其包含在该组件可接受的 prop 列表中:

组件内部声明prop

Vue.component(blog-post, { props: [title], template: <h3>{{ title }}</h3> })

父组件里调用               ,并给prop赋值,传递到组件内部

<blog-post title="My journey with Vue"></blog-post>

2.3                     、父组件监听子组件事件

其实就是通过在父组件声明方法                  ,并绑定在子组件上                     。以子组件内部触发方法的形式                  ,向父组件传参   ,实现子向父传值的效果          。如下

父组件中声明方法               ,并绑定在子组件上

<template> <lineChart v-on:getQuotaVal="getQuotaVal"></lineChart> </template> <script> methods: { // 本事件用来监听折线图子组件                  ,从子组件拿到指标数据 getQuotaVal:function(obj){ this.lineDateType = obj.lineDateType; // 这样父组件就拿到了      ,子组件的obj数据 } }, </script>

子组件触发方法

that.val = {}; that.$emit(getQuotaVal,that.val); // 将子组件的数据发送过去;

 2.4               、兄弟组件间交互

使用EventBus(事件总线)            ,vue.$bus.on和emit方法      。

初始化——全局定义                   ,可以将eventBus绑定到vue实例的原型上,也可以直接绑定到window对象上.

//main.js Vue.prototype.$EventBus = new Vue();

触发事件

this.$EventBus.$emit(eventName, param1,param2,...)

监听事件

this.$EventBus.$on(eventName, (param1,param2,...)=>{     //需要执行的代码 })

移除监听事件

      为了避免在监听时         ,事件被反复触发        ,通常需要在页面销毁时移除事件监听                    。或者在开发过程中                    ,由于热更新            ,事件可能会被多次绑定监听    ,这时也需要移除事件监听              。

this.$EventBus.$off(eventName);

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

v-if控制Dom是否存在                     ,v-show控制样式

4                  、vuex是什么?使用步骤大概说下

vuex是一个状态管理工具               ,集中式的管理所有组件的状态数据   。统一的去管理组件,将组件的状态抽象为一个store文件                  ,通过commit方法触发mutation里的函数来改变组件属性                   。

组件中可以使用computed属性监听数据的变化控制组件显隐等                  。如下举个loading组件的栗子

loading组件中根据Loading数据                  ,控制DOM显隐

<template> <div class="cover" v-show="Loading"> <div>加载中</div> </div> </template> <script> import Store from ../../store export default { name: "Loading", computed:{ Loading(){ return Store.state.Loading; } } } </script>

vuex集中管理状态   ,创建一个叫store的js文件

import Vuex from vuex; Vue.use(Vuex); export default new Vuex.Store({ state: { // Loading组件 Loading:false, }, mutations: { // Loading组件 ChangeLoading:function (State,Value) { State.Loading = Value; } }, });

 使用loading的组件中               ,这样操作

import Store from ../../store Store.commit("changeFooter",true);

vuex中 mutation和action的区别和使用?

5                  、vue watch和computed区别?

computed

        计算结果并返回                  ,只有当被计算的属性发生改变时才会触发(即:计算属性的结果会被缓存      ,除非依赖的响应属性变化才会重新及孙)。

        如上loading组件也有使用到computed属性               。

watch

        监听某一个值            ,当被监听的值发生变化时                   ,执行相关操作                     。

与computed的区别是         ,watch更加适用于监听某一个值得变化        ,并做对应操作                    ,比如请求后台接口等   。而computed适用于计算已有的值并返回结果            。 监听简单数据类型:

data(){ return{ first:2 } }, watch:{ first(){ console.log(this.first) } },

6   、Vue的虚拟Dom是什么?谈一谈对vue diff算法的认识?key的作用?

7               、谈谈对vue的双向绑定原理的理解?

双向绑定主要指修改数据时            ,无须操作DOM    ,视图会自动刷新                     。操作视图时绑定的数据也会跟随变动      。

数据 => 视图

vue在初始化实例时                     ,会用Object.defineProperty方法               ,给所有的数据添加setter函数,实现对数据变更的监听         。当数据被修改时                  ,生成新的虚拟DOM树                  ,跟老的虚拟DOM对比   ,根据对比结果找出需要更新的节点进行更新                     。

视图 => 数据

从视图到数据较为简单               ,视图变化后触发监听如oninput等                  ,在绑定的方法中修改数据          。

8                  、vue首屏优化怎么做?

使用较轻量的组件      ,比如echart对应有vue-chart vue-cli开启打包压缩 和后台配合 gzip访问; 路由懒加载            ,分包; 打包时配置删掉log日志 资源过大可以使用cdn模式引入                   ,不再打包到本地

9      、vue2的缺陷是什么?如何解决vue2.0数组中某一项改变         ,页面不改变的情况?

缺陷:数据如果为对象直接新增属性        ,如果为数组通过下标操作数组项                    ,页面无法触发更新      。

原因: Vue 会在初始化实例时对 property 执行 getter/setter 转化            ,所以 property 必须在 data 对象上存在才能让 Vue 将它转换为响应式的                    。关于数组作者通过重写push/pop/shift/unshift/splice/reverse/sort这些方法来实现数据的相应绑定    ,其余的操作无法触发页面更新;

对策:关于对象可以通过Vue.$set(obj,key,value)                     ,组件中通过this.$set(obj,key,value)实现新增               ,修改属性vue可以相应更新视图              。关于数组也可以通过Vue.$set(obj,key,value),或者作者重写的那些方法来操作;

10            、异步操作放在created还是mouted?

如果有些数据需要在初始化时就渲染的                  ,比如select下拉框的下拉内容                  ,在mouted中请求   。好处如下

页面初始化速度更快   ,减少用户等待时间 放在 created 中有助于一致性               ,因为ssr 不支持 beforeMount                   、mounted 钩子函数

11         、vue-router的钩子函数有哪些?

组件内部钩子:beforeRouterEnter()        、beforeRouterLeave                    、beforeRouterUpdate

12            、页面如何跳转?如何跨页面传参数?

router-link标签跳转 路由如下跳转                  ,顺便把参数传了                   。如下 this.$router.push({ path: /url, query: { par:parid } })

接受参数

var parid = this.$route.query.par;

13    、vue子组件的生命周期?子元素在什么时候挂载?

父:beforeCreate    首先初始化父原素 父:created              父原素挂载数据 父:beforeMounte    父原素开始挂载dom      ,tpl里遇到子组件 子:beforeCeate      子组件开始挂载数据 子:created              子元素数据挂载成功 子:beforeMount      子元素开始挂载dom 子:mounted            子元素dom挂载结束 父:mounted            父原素dom挂载结束 父:beforeUpdate     下面开始类似于dom事件流 子:beforeUpdate 子:updated 父:updated 父:beforeDestory 子:beforeDestory 子:destroyed 父:destoryed

子元素在父元素挂载dom时            ,开始加载                  。子元素一直到加载完毕dom后                   ,父原素结束dom挂载。后面就类似于dom事件流了               。

14                     、vue的import和node的require区别?

JS支持两种模块化方式         ,commonjs和ES6                     。

commonjs用于nodejs        ,同步加载模块   。ES6的import为了不卡顿                    ,异步加载模块            。

新版Nodejs也支持使用import            ,但是需要修改文件后缀名为.mjs    ,或者在package.json中                     ,制定type字段为module                     。

五:ES6

1               、箭头函数与es5函数区别?

箭头函数的this指向是固定的               ,普通的this指向是可变的 let a = { name: sunq, fn:function(action){ console.log(this.name + love + action); } } let b = {name:sunLi} // 正常的this指向调用他的对象 a.fn(basketball); // sunq love basketball // 改变this指向 a.fn.apply(b,[football]); // sunLi love football // 如果将a对象的fn函数改成箭头函数,this.name会是undefined // 箭头函数的this指向不会改变                  ,且总是指向函数定义生效时所在的对象      。 不可以当作构造函数                  ,不可以对箭头函数使用new命令   ,否则会抛出一个错误         。 var Person = function(name){ this.name = name; } let sunq = new Person(sq); // {name: sq} var Person = (name) => { this.name = name; } let sunq = new Person(sq); // 报错 Person is not a constructor 无arguments对象 不可以使用yield命令               ,因此箭头函数不能用作 Generator 函数                     。

2、ES6提供的解决异步交互的新方法?区别?

Promise                  、Genarate                  、async\await

3   、宏任务和微任务有哪些?执行顺序?

4               、先并行请求2个接口后                  ,再请求第3个接口      ,如何处理?

使用Promise.all()方法            ,将两个promise传入all方法                   ,拿到异步结果再请求第三个

明明知道的语法         ,面试官一问我偏偏就是跟实际场景联系不到一块        ,

5                  、js的数据类型

string number null undefined boolean object bigInt symbol

6      、说几个ES6新增的数组的方法  详情

map 实例方法                    ,类似于forEach            ,但是返回新数组

find和findIndex  实例方法    ,传入一个匿名函数                     ,ruturn出符合条件的项或下标

... 拓展运算符 基本功能是将一个数组转为用逗号分隔的参数序列

7            、for in和for of的区别

for in适合遍历对象               ,遍历数组拿到的是下标 for of适合遍历数组,遍历数组直接拿到数组的项          。for of只能遍历具备iterator接口的类型      。

8                   、多个数据请求                  ,如何顺序执行?

使用promise的then方法                  ,或者写多个promise   ,async中使用await顺序执行                    。

9         、proxy的理解               ,与defineProperty的区别?

proxy直接给所有属性设置拦截                  ,defineProperty只给指定的设置 proxy拦截后要用Proxy实例调用      ,defineProperty可以直接使用原对象 // es6的proxy let obj = {name:1,sex:2} let p = new Proxy(obj,{ get:(value,key)=>{ return sq的+obj[key] } }); p.name // sq的1 p.sex // sq的2 // es5的代理 let newObj = {name:1,sex:2} Object.defineProperty(newObj,name,{ get:function(val){ //defineProperty中get函数没有入参 return sq的 + val } }) newObj.name // sq的undefined newObj.sex // 2

10        、谈谈promise的原理?

六:ElementUI

1                    、如果需要修改样式怎么做?

再写一个样式表引入            ,!important覆盖 样式穿透

2            、如何通过继承扩展 element-ui 组件的功能?

通过继承扩展 element-ui 组件的功能_elementui扩展组件_在厕所喝茶的博客-CSDN博客

七:Jquery

1    、如何获取同一个cl下                   ,最后一个li?

$("#id").children().eq(3).remove(); // 获取多个class中的某一个 $(".className").eq(n).attr("class") // 可行 $(".className")[n].attr("class") // 不可行

2                     、window.load和$(document).ready()的区别?执行先后顺序?

window.onload必须等到页面内包括图片的所有元素加载完毕后才能执行              。 $(document).ready()是DOM结构绘制完毕后就执行         ,不必等到加载完毕   。通常简写为$()

总结:ready事件在load事件加载之前完成                   。

3               、如何绑定一个点击事件?

// 方式一 $("#id").on(click,function(){}); // 方式二 $("#id").click(function(){}); // 方式三 $("#id").bind("click",function(){});

4、Jquery常用动画?

八:Git的使用

1                  、常用哪些语句?

pull                  、commit   、push               、reset                  、merge      、log            、branch                   、stash

stash如何使用?

git stash -m xxx git stash pop

2         、版本回退语句?soft和hard区别?

git reset --soft 版本号

git reset --hard 版本号

soft会退后        ,代码改动在本地还保存的有                  。hard会删除本地改动                    ,彻底抹去该版本的痕迹。详情

3        、合并分支注意事项?

将自己分支合到目标分支前            ,最好先将目标分支合到自己分支上处理完冲突    ,再将自己的分支合回目标分支               。

4                    、如何进行分支管理?

九:敏捷开发

1            、什么是敏捷开发?

个人理解                     ,敏捷开发就是把一个大需求拆为多个独立的小需求                     。每个小需求可独立开发    、测试                     、上线               ,循序渐进的完成整个系统   。每个版本的周期可能比较短,比如2周                  ,或者4周            。

比如某公司需要开发维护一个巨大的平台                  ,可能把平台外包给多个公司干                     。如果用如上方法   ,并行开发               ,可显著缩减工期      。

如果想要保证每个版本又快又顺利的上线                  ,需要有完善的角色支持和流程规范         。

2               、敏捷开发的好处?

个人理解      ,当团队稍大            ,工期很紧时                   ,如何有条不紊的保证版本质量就需要一套有效的流程了                     。

比如一个团队同时收到3个需求         ,每个需求分发给多个前后端开发          。作为版本负责人或者项目负责人        ,如何把控每个人的代码质量、完成进度                  、过程留痕                  、风险规避                    ,其实是有难度的      。

一个需求如果经过            ,需求澄清   、方案设计               、设计评审                  、需求传递      、版本排期/评审            、开发划分                   、版本开发         、测试用例评审        、内部测试                    、代码评审            、灰度试用&测试    、版本发布                     、业务验收等完整的流程    ,可以有效地降低犯错的几率                    。也方便后期的查找责任人                     ,总结各环节的问题               ,提升团队的工作效率,使交付越来越平稳              。

十:开源项目

部分公司面试要求中有写                  ,维护有开源项目且具有50个star者优先   。

我平时有维护一个具备管理端/用户端/服务端的个人网站:sunqs blog

面试过程中无话可说时                  ,可以拿出来聊聊   ,缓解尴尬                   。

博客的代码全部开源:源码Github地址​​​​

十一:网络相关

1               、http和https的区别?

HTTP 明文传输               ,数据都是未加密的                  ,安全性较差      ,HTTPS(SSL+HTTP) 数据传输过程是加密的            ,安全性较好                  。 使用 HTTPS 协议需要到 CA(Certificate Authority                   ,数字证书认证机构) 申请证书         ,一般免费证书较少        ,因而需要一定费用。证书颁发机构如:Symantec、Comodo                  、GoDaddy 和 GlobalSign 等               。 HTTP 页面响应速度比 HTTPS 快                    ,主要是因为 HTTP 使用 TCP 三次握手建立连接            ,客户端和服务器需要交换 3 个包    ,而 HTTPS除了 TCP 的三个包                     ,还要加上 ssl 握手需要的 9 个包               ,所以一共是 12 个包                     。 http 和 https 使用的是完全不同的连接方式,用的端口也不一样                  ,前者是 80                  ,后者是 443   。 HTTPS 其实就是建构在 SSL/TLS 之上的 HTTP 协议   ,所以               ,要比较 HTTPS 比 HTTP 要更耗费服务器资源            。

2                  、常见状态码

200:成功返回 304:网页未更改有缓存                  ,未重新请求 404:请求资源不在 500:服务器内部错误 503:服务器超时

十二:webpack

1   、dependencies和devDependencies区别

安装时 --save -dev会放在devDependencies中      ,--save放在dependencies

devDependencies中安装的是开发环境使用的包            ,比如eslint               、vue-cli-serve;

dependencies中安装的是生产和开发环境下都需要使用的包                   ,比如vue                  、element      、vant等

devDependencies中的依赖模块         ,在生产环境下不会被打入包内

十三:页面优化

1            、某个页面加载较慢        ,从哪些方向分析                   、解决问题?

传统页面

首先判断是接口慢                    ,还是页面慢                     。如果接口慢            ,后端优化      。

如果前端页面加载慢    ,看是否是因为图片等资源过大                     ,尝试替换不同格式体积的图片         。定位是否是某些数据处理的函数               ,比较耗时                     。或者是否循环操作DOM,js生成dom后再批量插入          。

如果页面直接卡死                  ,就需要分析是否内存泄漏      。比如大屏展示的定时刷新卡死                  ,排查思路可如下:

使用chrome的任务管理器   ,操作页面观察的内存占用的变化                    。定位到是哪些操作               ,哪块代码导致内存占用飙升              。

因为js并没有直接释放缓存的语法                  ,只有靠浏览器的垃圾回收机制自动清理   。我们需要做的是及时给不需要的变量赋空                   。

特别注意大数据的循环实例化后      ,变量是否及时赋空                  。定时器等闭包方法中是否存在内存泄漏            ,循环渲染地图时                   ,是否先将之前地图数据清空等。

单页面应用

单页面一般不会某个页面加载慢         ,一般都集中在首屏加载时白屏较久               。处理方法可参考上文中                     。

2         、使用缓存

有些接口没必要每次打开页面都请求        ,可用cookie计时   。某个时间段内不重新获取            。 某些数据初始化时加载一次即可                    ,可通过cookie计时            ,某个时间段内不用请求                     。 某些数据可用localstorage存储    ,默认填充input                     ,更新时才重写缓存      。这个只是用户体验好些

十四:Node.js

1        、用过哪些插件(express中间件)?

cors   解决express的跨域问题 body-parser    解析post数据 mongoClient   mongodb官方提供的Node.js驱动 crypto  用来加密               ,添加签名 nodemailer  用来发邮件

2                    、mongodb和mysql的区别?

mongodb是文档型非关系型数据库,mysql是关系型数据库 mongodb以json形式存储数据                  ,字段可以随意添加                  ,mysql的字段需要提前确定好 mysql多表之间只能通过外键建立关系   ,mysql可以多层嵌套也可拆表并关联

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
公司网站seo基础优化论文(掌握自己公司网站SEO的5大技巧) 360浏览器收录网站(360网站收录提交:让你的网站优化起飞)