1、谈谈你对闭包的理解?【什么是闭包?作用?缺点?】
闭包:
可以访问另一个函数作用域中的变量函数。那首先我们就要了解什么作用域?
作用域?
作用域无非就是两种:全局变量和局部变量。
全局变量:就是在全局环境下声明的变量。全局变量在该环境下什么地方都可以被访问,除非你将这个应用程序关闭的时候将被销毁。缺点:全局变量容易被修改,容易造成全局变量污染等问题。
局部变量:只是在当前这个函数内部被访问,等到函数执行完毕后就会被销毁。
闭包?
当函数a的内部函数b被函数a外的一个变量引用的时候,就创建了一个闭包
作用:
1)能够读取函数内部的变量;
2)能够让这些变量始终保存在内存中;其变量和参数不会被垃圾回收机构回收
缺点:
1)最严重问题就是会造成内存浪费。因为闭包会使得函数中的变量被保存在内存中,内存消耗很好,所有不能乱用闭包,否则会造成网页性能问题。
2、请谈谈Cookie和session的弊端?
1、cookie理解
保存在浏览器端,保存的是字符串类型,以文本的形成存储,并且每个请求都会带上cookie信息。 若不在浏览器中设置过期时间,cookie被保存在内存中,生命周期随浏览器的关闭而结束,这种cookie称作为会话cookie。如果在浏览器中设置了cookie的过期时间,cookie会被保存在硬盘中,关闭浏览器后,cookie数据仍然会存在,直到过期时间结束后消失。
优点:
1)分担服务器存储的负担;
2、极高的扩展性和可用性。比如:只在cookie中存放不敏感的数据,即使被盗也不会有重大损失;控制cookie的生命周期,使之不会永远失效。偷盗者也只会拿到一个过期的cookie;
缺点:
1)cookie的数量和长度有限制(Ie6及更低的版本最多有20个cookie;Ie7和以后的版本最多有50个cookie,chrome和safari没有做硬性限制)。每个cookie的长度不能超过4kb,否则会被覆盖;
2)安全性问题。如果cookie被人拦截,偷盗者就有可能会获得 session;
3)cookie是随http事务一起被发送的,因此会浪费一部分发送的cookie的使用带宽;
4)cookie前端开发需要自己封装getCookie和getCookie
2、session理解
保存在服务器端,是以数据结构来保存,支持任何类型的对象(session可保安粗多个对象),并且没有大小限制。当服务器收到请求需要创建session对象时,首先会检查客户端请求中是否包含sessionid。如果有sessionid,服务器将根据该id返回对应session对象。如果客户端请求中没有sessionid,服务器会创建新的session对象,并把sessionid在本次响应中返回给客户端。
优点:
1)没有大小限制;
2)安全性比cookie高(seesionID存储在cookie中,若要攻破session首先要攻破cookie)
缺点:
1)依赖cookie(sessionID保存在cookie),如果禁用cookie,则要使用URL重写,不安全;
2)session保存的东西越多,就越会占用服务器内存。
所以个人建议:将登陆信息等重要信息存放在session中,其他信息如果需要保留,可以放在cookie中
3、浏览器本地存储WebStorage
针对h5以后本地存储相关的两个重要内容,webstorage。使用它可以在客户端本地建立一个数据库,原本必须保存在服务器端的数据库中的内容现在可以直接保存在客户端本地,这大大减轻了服务器端的负担,同时也加快了访问发数据的速度。localStorage(本地存储)和sessionStorage(会话存储)
优点:存储大小一般在5MB,都保存在客户端,不与服务器进行交互通信,是字符串类型。localStorage:常用于长期登录(判断用户是否已经登录),适合长期保存在本地的数据。sessionSession:敏感账号异性登录,它的生命周期使仅在当前会话下有效。
如果你是想用于临时保存同一窗口(或标签页)的数据,请使用sessionStorage。
4、解析下浮动和他的工作原理?清除浮动的技巧
浮动元素脱离文档流,不占据控件。浮动元素碰到他的边框或者浮动元素边框停留。
1)使用空标签清除浮动。
这种方法是在素有浮动标签后面添加一个空标签,定义css clear:both,弊端是增加了无意义的标签
2)使用overflow
给包含浮动元素的父标签添加css属性 overflow:auto;zoom:1 用于兼容ie6
3)使用after伪对象清楚浮动
该方法只适用于非IE浏览器。具体写法可参照以下示例。使用中需注意以下几点。一、该方法中必须为需要清除浮动元素的伪对象中设置 height:0,否则该元素会比实际高出若干像素;
5、浮动元素引起问题和解决办法?
浮动元素引起的问题:
(1)父元素的高度无法被撑开,影响与父元素同级的元素
(2)与浮动元素同级的非浮动元素(内联元素)会跟随其后
(3)若非第一个元素浮动,则该元素之前的元素也需要浮动,否则会影响页面显示的结构
清除浮动的几种方法:
1,额外标签法,<div style="clear:both;"></div>(缺点:不过这个办法会增加额外的标签使HTML结构看起来不够简洁。)
2,使用after伪类
#parent:after{
content:".";
height:0;
visibility:hidden;
display:block;
clear:both;
}
3,浮动外部元素
4,设置`overflow`为`hidden`或者auto
6、你如何对网站的文件和资源进行优化?
文件合并、文件最小化或者文件压缩、使用CDN托管、缓存的使用
7、请说出三种减少页面加载时间的方法
1)优化css;2)使用懒加载;3)减少http请求
vue知识
一、 import和require的用法
-
1、Import(模块、文件)引入方式
- 引入js文件
在用的那一页,引入文件
Import tools from ‘./tools.js’
相应的js文件,必须暴露出来
2.引入组件
Import Hello from ‘./components/hello’
3.引入外部组件
npm install --save axios
npm install mint-ui -S
//引入全部组件
import Vue from ‘vue’
import Mint from ‘mint-ui’
Vue.use(Mint)
//按需引入部分组件
Import {Cell,Checklist} from ‘minu-ui’
Vue.component(Cell.name,Cell)
Vue.component(Checklist.name,Checklist)
2、require.js的加载
相当于module.exports的传送门,module.exports后面的内容是什么,require的结果就是什么,对象、数字、字符串、函数……再把require的结果赋值给某个变量,相当于把require和module.exports进行平行空间的位置重叠
优点:
1)实现js文件的异步加载,避免网页失去响应;
2)管理模块之间的依赖性,便于代码的编写和维护。
引入:
require('./a')(); // a
模块是一个函数,立即执行a模块函数
var data = require('./a').data; // a
模块导出的是一个对象
var a = require('./a')[0]; // a模块导出的是一个数组注:
从理解上,require是赋值过程,import是解构过程,当然,require也可以将结果解构赋值给一组变量,但是import在遇到default时,和require则完全不同:
var $ = require('jquery');
import $ from 'jquery'
是完全不同的两种概念。
二、webpack的打包原理
1、webpack的基本能力:
处理依赖、模块化、打包
1、依赖管理:方便引用第三方模块,让模块更容易复用、避免全局注入导致的冲突、、避免重复加载或者加载不必要的模块
2、合并代码:把各个分散的模块集中打包成大文件,减少HTTP的链接的请求次数,配合uglify.js可以减少、优化代码的体积
3、各种插件:babel把ES6+转化为ES5-,eslint可以检查编译时的各种错误
2、webpack的工作原理
简单的说就是分析代码,找到“require”、“exports”、“define”等关键词,并替换成对应模块的引用。
在一个配置文件中,指明对某些文件进行编译、压缩、组合等任务。把你的项目当成一个整体,通过一个给定的主文件 (index.js),webpack将从这个文件开始找到你的项目的所有的依赖文件,使用loaders处理他们,最后打包为一个浏览器可 以识别的js文件。
三、webpack之Loaders
webpack只支持js和json两种文件类型,通过Loaders去支持其它文件类型并且把他们转换成有效的模块,并且可以添加到依赖图中
四、前端性能优化
1、减少http的请求,尽量合并js、css、图片。比如如果有5个css文件,则会请求5次http请求;
2、css放在顶部先加载渲染,js放在页面底部加载(加载js会对后续的资源造成堵塞,因为必须等到js加载造成后才去加载后续文件)
3、有些插件会用引用远程图片、css、js等,如果远程资源连接网络不佳,(比如ckeditor4加载数学公式mathquil,则会去加载国外的资源,网速慢,造成资源堵塞,则尽量把远程的医院下载到本地调用)
4、高并发的情况下,可将一些不怎么变化的东西缓存到浏览器的cache中
5、拆分代码,提升首屏打开速度,加载资源过大时,可以优化打包配置,将首屏不需要的内容单独打包,留到需要的时候异步加载,减少首屏等待时间;
6、内容过多,可以使用滚动懒加载;
7、使用v-for,需要配置v-key,key是每个节点下的唯一标识,使得diff算法更加准确。当组建无法匹配相同的,才从尾部去匹配,这样保证key相同的情况下数据也相同,dom就不会去做更新操作
五、什么是严格模式和非严格模式
1、什么是严格模式?
我们常规的js代码属于非严格模式,因为js是弱类型语言,存在许多类型错误,因此为了以后的js发展,添加了严格模式
2、严格模式如何实现?
只需在js脚本顶部加上use strict 即可
<script>
(functione(){
'use strict'
})()
</script>
3、严格模式与非严格模式的主要区别?
变量规范:非严格模式下,变量可以不进行声明,可直接赋值,严格模式中,变量必须声明才能赋值;
函数this指向:非严格模式下,普通函数指向Window,严格模式下,this为undefined;
构造函数调用:非严格模式下,构造函数可以直接调用,严格模式中不行;
删除变量:非严格模式下,可以使用delete删除已经声明的变量,严格模式下回报错;
在定时器函数中,this的指向都为window;
函数中传递的形参不能重复;
六、lable的for属性总结
1. 定义:for属性规定label与哪个表单元素绑定。
<label>是专门为<input>元素服务的,为其定义标记。
label 和表单控件绑定方式有两种:
方法一:将表单控件作为label的内容,这种就是隐士绑定。
此时不需要for属性,绑定的控件也不需要id属性。
隐式绑定:
<label>题型: <input type="text" name="tx" /></label>
方法二:为label标签下的for属性命名一个目标表单的id,这种就是显示绑定。
<label for="male">Male</label>
<input type="radio" name="tx" id="male" />
2、为什么要给label上面加上for属性
给 label 加了 for 属性绑定了input控件后,可以提高鼠标用户的用户体检。
如果在label 元素内点击文本,就会触发此控件,也就是说,当用户渲染该标签时,浏览器就会自动将焦点转到和标签相关的表单控件上。
<form>
<label >Male</label>
<input type="radio" name="题型" id="male" />
<br />
<label for="female">Female</label>
<input type="radio" name="sex" id="female" />
</form>
七、前端异常捕获
1、为什么前端需要统一的做异常处理?
增加用户体验、及早发现问题
2、需要处理哪些异常?
1)JS 语法错误、代码异常
2)静态资源加载异常
3)Promise 异常
4)Iframe 异常
5)跨域 Script error
6)崩溃和卡顿
3、几种异常处理手段
1)try…catch语句:报错的时候,线程执行已经进入try catch代码块 (异步、promise、语法错误不能捕获)
2)局异常监听window.onerror:能捕获同步、异步处理,不try catch稍微强一点 (语法错误、网络(接口)错误、静态资源异常、Promise 错误、 iframe 的错误、.vue文件发生不能捕获)
注意:
1、window.onerror 函数只有在返回 true 的时候,异常才不会向上抛出,否则即使是知道异常的发生控制台还是会显示;
2、 window.onerror 捕获异常最好现在所有js脚本前面。因为你无法保证你写的代码是否出错,如果写在后面,一旦发生错误的话是不会被 onerror 捕获到的。3、区别window.onerror与window.addEventListener
window.onerror = function(message, source, lineno, colno, error) { ... } 函数参数: * message:错误信息(字符串)。可用于HTML onerror=""处理程序中的event。 * source:发生错误的脚本URL(字符串) * lineno:发生错误的行号(数字) * colno:发生错误的列号(数字) * error:Error对象 若该函数返回true,则阻止执行默认事件处理函数,如异常信息不会在console中打印。没有返回值或者返回值为false的时候,异常信息会在console中打印 window.addEventListener( "error", (e) => { console.log(e); //TODO:上报逻辑 return true; }, true );
3)Vue.config.errorHandler:捕获.vue文件发生
4)promise内部异常,通常用catch捕获,但一般会忘写,则可全局对处理未捕获的异常
window.addEventListener("unhandledrejection", (e) => {
throw e.reason;
});
5)Vue.config.warnHandler:语法警告异常捕获
Vue.config.warnHandler = function (msg, vm, trace) {
console.log(`警告提示: ${msg}\nTrace: ${trace}`);
}
4、几种异常处理总结
import { createApp } from "vue";
import App from "./App.vue";
let app = createApp(App);
//统一处理js运行时异常
window.addEventListener(
"error",
(e) => {
console.log(`错误提示:${e}`);
return true;
},
true
);
//处理未捕获的异常,主要是promise内部异常,统一抛给 onerror
window.addEventListener("unhandledrejection", (e) => {
throw e.reason;
});
//捕获Vue warning,生产环境不起作用
Vue.config.warnHandler = function (msg, vm, trace) {
console.log(`警告提示: ${msg}\nTrace: ${trace}`);
}
// 框架异常统一捕获
Vue.config.errorHandler = function (err, vm, info) {
console.log(`错误提示: ${err.toString()}\nInfo: ${info}`);
}
app.mount("#app");
5、js中“==”与"==="的区别
== 表示相等 (值相等)
===表示恒等(类型和值都要相等)
js在比较的时候如果是 == 会先做类型转换,再判断值得大小,如果是===类型和值必须都相等。
6、svg图片和png图片差别
svg:
1、矢量图,不受于屏幕分辨率的影响(可随意改变大小);
2、可以用CSS样式自由定义图标颜色,尺寸等;
3、所有的SVG可以全部放在一个文件中,节省HTTP请求;
4、SVG也是一种XML文件,所以可以使用gzip的方法把文件压缩到很小
与icon font对比
icon font采用的是字体渲染,icon font在一倍屏幕下渲染效果并不好,在细节部分锯齿还是很明显的,SVG上面我说过它是图形所以在浏览器中使用的是图形渲染,所以SVG却没有这种问题,请看下图对比
icon font的性能测试也没有svg好
7、sessionStorage清空所有缓存或者单项值方法
1)清空所有缓存:sessionStorage.clear()
2)删除某一项值:localStorage.removeItem(“xxx”)
8、css使用作用域scoped和深度选择器/deep/以及>>>对比
1)scoped属性
当给<style scoped> </style>添加 scoped 属性之后,它会给每一个class添加一个唯一的属性值,避免了出现类名重复,样式重叠被污染的问题,相当于限制了作用域,它的 CSS 只作用于当前组件;
// 编译前
.className {
background: red;
}
// 编译后。
.className[data-el-v09ew9w] {
background: blue;
}
2、深度选择器
因为scoped属性,限制了作用域,父组件的样式不能应用到子组件上,所以需要深度选择器/deep/和>>>
// 非css语言预处理器,可以使用>>>或者/deep/
.parentElementClassName >>> .childrenElementClassName {
background: red;
}
// less或scss,只能使用/deep/
.parentElementClassName /deep/ .childrenElementClassName {
background: blue;
}