总结自己以及其他几位面试者的部分面试题
1、MD5加密
下载插件 在计算属性中 添加
将前端的值或者内容加密 例如将password类型改成text可以看到密码
2、数组,some方法
摘自:https://blog.csdn.net/wang729506596/article/details/83019131
1.push() 后增
push()方法可以向数组后添加一个新的元素,并返回新数组的长度。
末尾添加,返回长度,改变原数组
2.unshift() 前增
unshift()可以向数组前添加一个或多个元素,并返回新的长度
首部添加,返回长度,改变原数组
3.pop() 后删
pop() 用于删除并返回最后一个元素。
尾部删除,返回被删除的元素,改变原数组
4.shift() 前删
shift() 用于删除并返回首个元素
删除首部元素,返回被删元素,改变原数组
\5. splice() 修该删除
splice(index,length,增加的元素1,增加的元素2…,增加的元素N) 表示从index开始删除length个元素,并从index开始新增元素1~N,放回被删除的元素组成的数组
对数组进行删除修改,返回被删除的元素组成的数组,改变原数组
6.concat() 拼接
concat() 方法用来合并两个或多个数组
合并两个或多个数组,返回新数组,不会改变原数组
7.slice() 剪切
slice(startIndex,endIndex) 返回从startIndex开始(包括),到endIndex(不包括)之间的原属组成的数组
返回新数组,不改变原数组
8.join()
join() 方法用来将数组转换为字符串
不改变原数组,返回转换后的字符串
9.sort() 排序
按ascii码排序
改变原数组,返回排序后的数组
10.reverse() 颠倒顺序
reverse() 方法用于颠倒数组中元素的顺序。
返回的是颠倒后的数组,会改变原数组。
11.indexOf()和lastIndexOf()
indexOf(某元素,startIndex) 从startIndex开始,查找某元素在数组中的位置,若存在,则返回第一个位置的下标,否则返回-1
lastIndexOf(某元素,startIndex) 和indexOf()相同,区别在于从尾部向首部查询
不会改变原数组,返回找到的index,否则返回-1
若不使用下标,则一般通过includes()方法代替indexOf()
12.filter() 过滤
filter() 方法返回数组中满足条件的元素组成的新数组,原数组不变
filter()的参数是一个方法
13.map() 格式化数组
map() 方法来根据需求格式化原数组,返回格式化后的数组。原数组不变
14.every()
对数组的每一项都运行给定的函数,若每一项都返回 ture,则返回 true
15.some()
对数组的每一项都运行给定的函数,若存在一项或多项返回 ture,则返回 true
16.forEach() 数组遍历
遍历整个数组,中途不能中断
3、插槽(作用)
作用:插槽可以对已有组件的结构进行自定义
-
默认插槽:
在组件标签中间可以传递一些子节点
组件内部利用slot标签进行接收
-
具名插槽
在组件标签中间通过定义slot的名字传递子节点
<my-banner>
<div slot="header">
头部
</div>
<div slot="footer">
底部
</div>
</my-banner>
组件内部利用slot的name进行对应接收
<template id="banner">
<div>
<slot name="header"></slot>
<slot name="footer"></slot>
</div>
</template>
-
作用域插槽
在组件内部定义数据,将数据传递给插槽的结构
通过给slot动态绑定属性
<template id="my-li"> <ul> <li v-for="item in arr"> <slot :row="item"></slot> </li> </ul> </template>
插槽内部:通过slot-scope=“scope”来接收
<my-li> <template slot-scope="scope"> <p>{{scope.row}}</p> </template> </my-li> <my-li> <template slot-scope="scope"> <a href="04-侦听器.html">{{scope.row}}</a> </template> </my-li>
4、jquery创建数组
1.
//创建一个测试数组
var array = new Array();
boxIds.push(12182);
boxIds.push(12183);
boxIds.push(12184);
2.
var arr = new Array();
arr[0] = 1;
arr[1] = "a";
arr[2] = '无线';
3.
var a = new Array(1, 2, 3, 4, 5);
var b = [1, 2, 3, 4, 5];
4.多维数组
(1).
var a = new Array();
a[0] = new Array();
a[0][0] = 1;
(2).
var a = new Array([1,2,3], [4,5,6], [7,8,9]);
var b = [[1,2,3], [4,5,6], [7,8,9]];
5、生命周期
生命周期:是指一个对象从创建到运行到销毁的整个过程,被称为生命周期
生命周函数:在不同的生命周期阶段会自动执行对应的函数,而这些函数则被成为生命周期函数
// 创建阶段
beforeCreate() {
// 这个生命周函数,代表开始创建实例了
console.log('beforeCreate',this.num)
},
created () {
// 代表数据和方法已经初始化成功了,此处dom还没有挂载到页面上
console.log('created',this.num,this.$el)
},
beforeMount () {
// 挂在之前
console.log('beforeMount',this.$el)
},
mounted () {
// dom已经挂载了
console.log('mounted',this.$el)
},
// 运行更新阶段
beforeUpdate () {
// 数据更新,页面还没有同步
console.log('beforeUpdated',this.num,document.getElementById('app').innerHTML)
},
updated () {
// 数据更新,页面已经同步
console.log('updated',this.num,document.getElementById('app').innerHTML)
},
// 销毁阶段
beforeDestroy () {
// 销毁之前
console.log('beforeDestroy')
},
destroyed () {
// 已经销毁了
console.log('destroy')
}
6、回调函数场景
异步的时候,回调拿到异步的结构
7、CMD、AMD
- 按下enter键会执行的流程
- 首先会根据这个域名发送请求 将域名传送到服务器 跟服务器上的ip地址匹配 返回数据给客户端
AMD 是 RequireJS 在推广过程中对模块定义的规范化产出。
CMD 是 SeaJS 在推广过程中对模块定义的规范化产出。
区别:
- 对于依赖的模块,AMD 是提前执行,CMD 是延迟执行。
- CMD 推崇依赖就近,AMD 推崇依赖前置
- AMD 的 API 默认是一个当多个用,CMD 的 API 严格区分,推崇职责单一。
8、在created中操作DOM
这个函数是可以等dom重新更新完成会调用
数据渲染完成,页面完成更新即调用this.$nextTik
当修改了数据,dom是异步同步的,所以,如果更改了数据,在修改数据下面重新操作dom会出问题,需要保证dom也更新完成才能操作
9、watch和computed的区别
computed是计算属性,依赖其它属性值,并且computed的值有缓存,只有它依赖的属性值发生改变,
下一次获取computed的值才会重新计算computed的值
watch更多的是[观察]的作用,类似某些数据的监听回调,每当监听的数据变化时都会执行回调进行后续操作
当我们需要数值计算,并且依赖其它数据时,应该使用computed,因为可以利用computed的缓存特性,避免每次获取值,都要重新计算;
当我们需要在数据变化时执行异步或开销较大的操作时,应该使用watch,使用watch选项允许我们执行异步操作,限制我们执行操作大的频率,
并且在我们得到最终结果前,设置中间状态,这些都是计算属性无法做到的。
10、常见web安全及防护原理
xss、sql注入原理
sql注入原理
具体就是通过把sql命令插入到web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意sql命令
xss
跨站脚本(Cross-site Scripting)是一种网站应用程序的安全漏洞攻击,是代码注入的一种。它允许恶意用户将代码注入到网页上,其他用户在观看网页时就会受到影响。这类攻击通常包含了HTML以及用户端脚本语言。
11、哪些操作会造成内存泄露
js造成内存泄漏的几种情况:
全局变量 闭包引起的内存泄露 没有清理的DOM元素引用 被遗忘的定时器或者回调 子元素存在引起的内存泄露
12、null和undefined的区别
null作为函数的参数,表示该函数的参数不是对象,作为对象原型链的终点,null表示”没有对象”,即该处不应该有值。典型用法是
null表示空 undefined定义后未赋值
13、Js怎么实现继承
摘自:https://www.cnblogs.com/humin/p/4556820.html
首先创建一个父类:
1、原型链继承 核心: 将父类的实例作为子类的原型
2、构造继承 **核心:**使用父类的构造函数来增强子类实例,等于是复制父类的实例属性给子类(没用到原型)
3、实例继承 **核心:**为父类实例添加新特性,作为子类实例返回
5、组合继承 **核心:**通过调用父类构造,继承父类的属性并保留传参的优点,然后通过将父类实例作为子类原型,实现函数复用
6、寄生组合继承 **核心:**通过寄生方式,砍掉父类的实例属性,这样,在调用两次父类的构造的时候,就不会初始化两次实例方法/属性,避免的组合继承的缺点
4、拷贝继承
function Cat(name){
var animal = new Animal();
for(var p in animal){
Cat.prototype[p] = animal[p];
}
Cat.prototype.name = name || 'Tom';
}
// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // false
console.log(cat instanceof Cat); // true
14、实现一个Js数组的去重
摘自:https://www.jb51.net/article/118657.htm
1、双层循环,外层循环元素,内层循环时比较值
如果有相同的值则跳过,不相同则push进数组
2、利用splice直接在原数组进行操作
双层循环,外层循环元素,内层循环时比较值
值相同时,则删去这个值
注意点:删除元素之后,需要将数组的长度也减1.
3、利用对象的属性不能相同的特点进行去重
4、数组递归去重
运用递归的思想
先排序,然后从最后开始比较,遇到相同,则删除
5、利用indexOf以及forEach
6、利用ES6的set
Set数据结构,它类似于数组,其成员的值都是唯一的。
利用Array.from将Set结构转换成数组
function dedupe(array){
return Array.from(new Set(array));
}
dedupe([1,1,2,3]) //[1,2,3]
// 拓展运算符(...)内部使用for...of循环
let arr = [1,2,3,3];
let resultarr = [...new Set(arr)];
console.log(resultarr); //[1,2,3]
7、concat()方法
思路:concat() 方法将传入的数组或非数组值与原数组合并,组成一个新的数组并返回。该方法会产生一个新的数组。
function concatArr(arr1, arr2){
var arr = arr1.concat(arr2);
arr = unique1(arr);//再引用上面的任意一个去重方法
return arr;
}
15、vue生命周期的理解
同上
16、 r o u t e 、 route、 route、router的区别
route是当前路由信息,可以获取到当前路由地址参数等等
router是全局路由(VueRouter)实例对象,可以通过router进行路由的跳转后退等等
$route为当前router跳转对象里面可以获取name、path、query的值;
$router为Vue-router实例;
想要导航到不同URL,则使用$router.push方法
17、Vue中怎么自定义过滤器
在组件内部通过filters来创建一个局部过滤器
全局过滤器和局部过滤器的区别
局部过滤器:只能在当前的组件中使用
全局过滤器: 在任意地方使用
18、H5标签有哪些?
h5标签,:内容标签article,footer,header;表单:date,time,Email;媒体video,audio,本地缓存:localstorage,sessionstorage等
19、css画一个响应式正方形(请勿直接使用vw、vh、rem)
正方形
position:absolute;
border:1px solid red;
padding: 0 20% 20% 0;
20、缓存的几种方式以及区别
cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递。而sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存
cookie数据不能超过4k sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。
21、ES6数组的新方法有哪些
map 、reduce 、filter、some、sort、reverse(倒序)
- find()
找到数组中第一次满足条件的元素,并返回,若找不到则返回undefined。不改变原数组。
和filter()方法的区别在于:filter返回值是所有满足条件的元素组成的数组,
一般在需要使用找到的元素时,用find()方法
2.findIndex()方法
findIndex()的作用同indexOf(),返回第一个满足条件的下标,并停止寻找。
区别是findIndex() 的参数为一个回调函数,且一般用于对象数组
3.includes()
includes()方法,返回一个布尔值。 参数是一个value,一般用于简单数组。
对于复杂数组,则可以使用some()方法替代includes()方法
4.Array.isArray()方法
用来判断一个元素是否为数组
22、实现一个js数组去重
// 数组去重
var arr = [1,2,3,4,5,4,3,2,1]
function fn(arr) {
let newArr = []
for(let i = 0;i < arr.length;i++) {
if(!newArr.includes(arr[i])) {
newArr.push(arr[i])
}
}
return newArr
}
console.log(fn(arr));
23、怎么清除cdn 浏览器缓存
24、用过es6的api么,对象的,数组的,还有函数里面的
25、请写出一个函数,给定任意一个值,判断其属于JavaScript中的哪一种数据类型
function type(val) {
// ... 写出你的实现方法
return Object.prototype.toString.call(val)
}
let a = 3; // type(a) => 'Number'
let b = [2, 1]; // type(b) => 'Array'
let c = (a, b) => a+b; // type(c) => 'Function'
let d = { a, b } // type(d) => 'Object'
let e = null // type(d) => 'Null'
let f = /\.png$/ // type(f) => 'RegExp'
let g = Symbol('fool') // type(g) => 'Symbol'
Object.prototype.toString.call(null); // "[object Null]"
Object.prototype.toString.call(undefined); // "[object Undefined]"
Object.prototype.toString.call('abc');// "[object String]"
Object.prototype.toString.call(123);// "[object Number]"
Object.prototype.toString.call(true);// "[object Boolean]"
console.log(type(a))
console.log(type(b))
console.log(type(c))
console.log(type(d))
console.log(type(e))
console.log(type(f))
console.log(type(g))
26、怎么清除cdn缓存
-
只要重新同步一次最新的,之前缓存就都没了
-
1.打开命令对话框:开始–cmd–确定
2.在CMD命令操作框上输入清空DNS缓存的命令,命令为:ipconfig/flushdns ,然后回车即可清除DNS缓存。
27、怎么清除cookie
浏览器–设置–清除cookie
28、ES6 解构
29、webpack
- 1> 连接: webpack从入口JS开始, 递归查找出所有相关联的模块, 并
连接
起来形成一个图(网)的结构 - 2> 编译: 将JS模块中的模块化语法
编译
为浏览器可以直接运行的模块语法(当然其它类型资源也会处理) - 3> 合并: 将图中所有编译过的模块
合并
成一个或少量几个bundle文件, 而浏览器运行是打包生成的bundle文件 - 说说你对项目构建的理解
1). 构建项目到底做些什么 编译项目中的js, sass, less, stylus 合并js/css等资源文件 压缩js/css/html等资源文件 JS语法的检查 2). 构建工具 作用: 简化项目构建, 实现自动化构建 常用: grunt/gulp/webpack - 区别webpack与gulp/grunt
1). webpack是一种模块化打包工具,主要用于模块化方案,预编译模块的方案。
2). Grunt/Gulp是非模块化打包工具, 是工具链,可以配合各种插件做js压缩,css压缩,less编译 替代手工实现自动化工作
30、将下列数组相同name属性的num,并倒序排列
let list = [
{ name: 'a', num: 1},
{ name: 'a', num: 1},
{ name: 'b', num: 2},
{ name: 'b', num: 2},
{ name: 'c', num: 3},
{ name: 'c', num: 3},
{ name: 'd', num: 9},
]
const newList = []
list.forEach(item => {
const index = newList.findIndex(newItem => newItem.name === item.name )
// 如果没有符合条件的元素返回 -1
if (index !== -1) {
newList[index].num += item.num
} else {
newList.push(item)
}
})
// sort() 方法用于对数组的元素进行排序
console.log(newList.sort((a,b) => {
return b.num - a.num
}))
31、将多维数组转化为一维数组
<script>
var arr = [1,2,3,[4,5,6,[7,8,9,[10,11]]],[111,222]]
// join方法
// const newArr = arr.join(',')
// toString方法
// const newArr = arr.toString().split(',').map(item => item - 0)
// flat方法
// const newArr = arr.flat(Infinity)
// 递归方法
const newArr = []
function deep(arr2) {
arr2.forEach(item => {
if (typeof item === 'object') {
deep(item)
} else {
newArr.push(item)
}
})
}
deep(arr)
</script>
32、问题: 项目中获取数据失败404,代码无误||或者,面试官:你开发的项目中有没有遇到比较难解决的问题,你在写项目的时候,功能有什么亮点?
有的,当时在开发项目的时候,遇到了一个这样的问题,就是后台返回的数据的id,和我拿到的id不一样,这个问题困扰了好久,最后发现数值大于2的53次方之后,数值就不精确了,后台返回的数据超过了2的53次方。终于找到了bug的具体问题。后来又发现后台返回数据的时候axios帮我处理了这个数据,最终处理的有问题,所以,我就不打算让axios处理响应的数据了,所以就需要获取到后台返回的源数据,axios.create内部的transformResponse就可以获取到源数据,又遇到新的问题,如何自己处理后台返回的的数据包含大数的问题,最终在网上找了好久,终于找到了一个插件json-bigint这个插件,利用这个插件的parse方法即可处理大数,但是 json-bigint在处理大数的时候将大数处理成了一个对象,还需要将这个处理之后的对象转成字符串才可以使用
后台返回的是字符串, axios 转为json数据,数值超过2的53次方,就不精确了,易出错 (是axios转换导致的错误404)
原因:文章、id不对、(id过长)
从network中找到后台返回数据 id,与vue调试工具中的 id 对比 发现id值不一样
解决:利用json-bigint处理大数字问题
json-bigint 是一个第三方包,它可以帮我们很好的处理这个问题。
json-bigint 会把超出 JS 安全整数范围的数字转为一个 BigNumber 类型的对象,对象数据是它内部的一个算法处理之后的,我们要做的就是在使用的时候转为字符串来使用。
通过 Axios 请求得到的数据都是 Axios 处理(JSON.parse)之后的,我们应该在 Axios 执行处理之前手动使用 json-bigint 来解析处理。Axios 提供了自定义处理原始后端返回数据的 API:transformResponse
。
34、项目优化:
1.项目优化- -进度条添加搜索npr ogr ess进行安装即可
2.移除打包之后的console
npm install babel-plugin-tr ans for m-r emove-console --save-dev打开babel. config.js文件在
plugins节点下新增"tr ans form-r emove-console"
3.只在发布阶段移除console
利用pr ocess . env. NODE_ ENV判断当前是发布是开发阶段
利用展开运算符将数组里面的插件交给plugins
4.双击打开页面
创建> vue . config. js文件
js内部暴露出- -个配置对象
publicPath: './'将根路径修改为相对路径
5.根据不同的环境配置不同的入口文件
6.通过cdn加载外部资源
7.配置element -ui的cdn资源
8.根据不同环境定制不同的首页内容
9.实现路由懒加载
npm insta1ll --save-dev @babel/p1ugin-syntax- dynamic- import配置babe1-plugins
//引入路由懒加载
“@babe1/p lugin-synt ax-dynami c- import”
修改引入方式,相同的组webpackChunkName相同
35、浏览器兼容问题
1、Vue的话借助postCsschain解决兼容
2、html5Shiv解决h5标签兼容
3、response.js解决媒体查询兼容
36、cookie与session区别
摘自:https://www.cnblogs.com/pengc/p/8714475.html
cookie和session都是用来跟踪浏览器用户身份的会话方式。
1、保持状态:cookie保存在浏览器端,session保存在服务器端
2、使用方式:(1)cookie机制:如果不在浏览器中设置过期时间,cookie被保存在内存中,生命周期随浏览器的关闭而结束,这种cookie简称会话cookie。如果在浏览器中设置了cookie的过期时间,cookie被保存在硬盘中,关闭浏览器后,cookie数据仍然存在,直到过期时间结束才消失。
Cookie是服务器发给客户端的特殊信息,cookie是以文本的方式保存在客户端,每次请求时都带上它
(2)session机制:当服务器收到请求需要创建session对象时,首先会检查客户端请求中是否包含sessionid。如果有sessionid,服务器将根据该id返回对应session对象。如果客户端请求中没有sessionid,服务器会创建新的session对象,并把sessionid在本次响应中返回给客户端。通常使用cookie方式存储sessionid到客户端,在交互中浏览器按照规则将sessionid发送给服务器。如果用户禁用cookie,则要使用URL重写,可以通过response.encodeURL(url) 进行实现;API对encodeURL的结束为,当浏览器支持Cookie时,url不做任何处理;当浏览器不支持Cookie的时候,将会重写URL将SessionID拼接到访问地址后。
3、存储内容:cookie只能保存字符串类型,以文本的方式;session通过类似与Hashtable的数据结构来保存,能支持任何类型的对象(session中可含有多个对象)
4、存储的大小:cookie:单个cookie保存的数据不能超过4kb;session大小没有限制。
5、安全性:cookie:针对cookie所存在的攻击:Cookie欺骗,Cookie截获;session的安全性大于cookie。
原因如下:(1)sessionID存储在cookie中,若要攻破session首先要攻破cookie;
2)sessionID是要有人登录,或者启动session_start才会有,所以攻破cookie也不一定能得到sessionID;
(3)第二次启动session_start后,前一次的sessionID就是失效了,session过期后,sessionID也随之失效。
(4)sessionID是加密的
5)综上所述,攻击者必须在短时间内攻破加密的se
37、路由组件传参的所有方式
分别为:布尔模式、对象模式、函数模式。
组件中:通过this. r o u t e r . p u s h 进 行 编 程 式 路 由 跳 转 、 r o u t e r − l i n k 中 的 t o 属 性 进 行 路 由 切 换 。 通 过 t h i s . router.push进行编程式路由跳转、router-link中的to属性进行路由切换。通过this. router.push进行编程式路由跳转、router−link中的to属性进行路由切换。通过this.route.params/this.$route.query获取路由传递的参数**。
总结:
1.this,
r
o
u
t
e
r
.
p
u
s
h
进
行
编
程
式
路
由
跳
转
2.
r
o
u
t
e
r
−
l
i
n
k
进
行
页
面
按
钮
式
路
由
跳
转
3.
t
h
i
s
.
router.push进行编程式路由跳转 2.router-link进行页面按钮式路由跳转 3.this.
router.push进行编程式路由跳转2.router−link进行页面按钮式路由跳转3.this.route.params获取路由传递参数
4.this.$route.query获取路由传递参数
5.params和query都是传递参数区别在于params不会再url上显示出现,
并且params参数是路由的一部分,是一定要存在的,否则无法显示视图。
query则是我们通常看到的url后面跟上的?后跟的显示参数
###39、js数组方法,哪个方法会改变原函数,es6新增特性