原地址:https://blog.csdn.net/Mr_JavaScript/article/details/84311068
1. flex布局:又叫做弹性布局
任何一个容器都可以指定flex布局,如display:flex 或 display:inline-flex
注意:设置了flex布局以后,子元素的float,clear,vertical-align属性将失效
容器的属性:
flex-direction flex-wrap flex-flow justify-content align-items align-content
2. js有哪些遍历数组的方法
es5方法:
(1)for循环:通过下标遍历数组的每一项
(2)array.forEach(item, index, array)
(3) array.map(item, index, array => return 格式化数组)
(4) array.filter(item, index, array => return 过滤条件)
(5) array.every(((item, index, array)=>{ return //判断条件 }))
如果每个元素都符合条件,则返回true,否则返回false;
6)array.some(((item, index, array)=>{ return //判断条件 }))
只要有一个元素符合条件,就返回true,否则返回false;
7)array.reduce((prev,cur,index,array)=>{})
从左到右遍历数组,并返回回调函数的值(应用于求和,求幂等);prev为上一轮函数执行结果(previousResult),cur为当前值(currentValue)
8)array.reduceRight((prev,cur,index,array)=>{})
从右到左遍历数组,并返回回调函数的值;
ES6方法:
1)for(let item of array){ //等到每个元素 }
for(let index of array.keys()) { //keys()返回数组的键(index) }
for(let keyAndValue of array.entries()){ //entries()返回数组的键值对(index:element) }
2)array.find((value, index, array)=>{ return //条件 }
返回第一个符合条件的元素,如果没找到返回undefined(找到第一个符合条件的元素,则停止遍历)
3)array.findIndex((value, index, array)=>{ return //条件 }
返回第一个符合条件的元素下标,如果没找到则返回-1(找到第一个符合条件的元素,则停止遍历)
3、箭头函数的特性
1)箭头函数是匿名函数,自身没有this和arguments,它的this从上下文捕捉而来;
2)箭头函数不能作为构造函数,和 new 一起用就会抛出错误;
3)箭头函数没有原型属性(prototype);
4)箭头函数不能当做Generator函数,不能使用yield关键字;
5、MVVM模式介绍
MVVM 是Model-View-ViewModel 的缩写,它是一种基于前端开发的架构模式,其核心是提供对View 和 ViewModel 的双向数据绑定,这使得ViewModel 的状态改变可以自动传递给 View,即所谓的数据双向绑定。
beforeCreate() 创建组件
created() 创建完成
beforeMounte() 组件被挂载前
mounted() 组件挂载完成
beforeUpdate() 组件更新前
updated() 组件更新后
beforeDestory() 组件摧毁前
destoryed() 组件摧毁后
7、Vue数据双向绑定原理
vue.js是采用数据劫持结合发布者-订阅者模式的方式实现数据双向绑定,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调,从而更新视图层的数据。
详细介绍:剖析Vue原理&实现双向绑定MVVM
vue的数组如何实现的双向绑定
9、web缓存
http请求头缓存
1)强制缓存:
第一次请求即把数据缓存起来,在缓存数据未失效的情况下,之后的请求都直接使用缓存数据。
缓存规则(header里配置) Cache-Control,参数:private(客户端可以缓存),public(客户端和代理服务器都可缓存),max-age=xxx 缓存时长(s),no-cache使用缓存前,再向服务器发送验证请求,no-store禁止缓存。
2)协商缓存:
第一次请求时拿到缓存数据和缓存标识,再次请求时向服务器发送缓存标识,服务器判断缓存是否有效,若有效则返回304状态码,请求数据从缓存读取,若无效则返回202,需要重新发送http请求数据。
缓存数据的修改时间(header里配置) Last-Modified(第一次请求) 数据最后修改时间,If-Modified-Since(再次请求)上次请求时的最后修改时间。
缓存标识(header里配置):Etag(第一次请求)由服务器生成的唯一标识,If-None-Match(再次请求)第一次请求获取的唯一标识。
常用浏览器缓存
1)Cookie主要用于用户信息的存储,Cookie的内容可以自动在请求的时候被传递给服务器;
2)LocalStorage的数据将一直保存在浏览器内,直到用户清除浏览器缓存数据为止;
3)SessionStorage的其他属性同LocalStorage,只不过它的生命周期同标签页的生命周期,当标签页被关闭时,SessionStorage也会被清除;
4)IndexDB主要用在前端有大容量存储需求的页面上,例如,在线编辑浏览器或者网页邮箱。
10、web跨域方式
同源策略:协议,域名,端口三者中有一个不同就算跨域。
跨域方式:
1)JSONP,通过<script>标签的异步加载来实现的跨域;
2)CORS “跨域资源共享”(Cross-origin resource sharing),它允许浏览器向跨源服务器,发出XMLHttpRequest请求。分为简单请求和非简单请求;(浏览器自动完成)
3)WebSocket(网络通信协议),不受同源的限制,可在客户端和服务器端之间双向通信;(客户端可以向服务器发送请求,服务器也可以向客户端发送请求,而http只能由客户端向服务器发送请求,不能反过来)
4)postMessage(),H5新增的跨域通信方法。应用场景:窗口 A (http:A.com)向跨域的窗口 B (http:B.com)互通信息;
5)Hash,原理:Hash的改变,页面不会刷新。应用场景:A 通过iframe或frame嵌入了跨域的页面 B,A与B间可以通过hash通信。(A和B的domain相同)
12、大数的加减乘除
1)使用插件:如bignumber.js、bigInteger.js
2)原生js实现:javascript 大数值数据运算
13. 判断两个单链表是否相交及找到第一个交点
如果两个单链表有共同的节点,那么从第一个共同节点开始,后面的节点都会重叠,直到链表结束。
因为两个链表中有一个共同节点,则这个节点里的指针域指向的下一个节点地址一样,所以下一个节点也会相交,依次类推。所以,若相交,则两个链表呈“Y”字形。如下图:
1.暴力解法。
从头开始遍历第一个链表,遍历第一个链表的每个节点时,同时从头到尾遍历第二个链表,看是否有相同的节点,第一次找到相同的节点即第一个交点。若第一个链表遍历结束后,还未找到相同的节点,即不存在交点。时间复杂度为O(n^2)。这种方法显然不是写这篇博客的重点。。。不多说了。
2.使用栈。
我们可以从头遍历两个链表。创建两个栈,第一个栈存储第一个链表的节点,第二个栈存储第二个链表的节点。每遍历到一个节点时,就将该节点入栈。两个链表都入栈结束后。则通过top判断栈顶的节点是否相等即可判断两个单链表是否相交。因为我们知道,若两个链表相交,则从第一个相交节点开始,后面的节点都相交。
若两链表相交,则循环出栈,直到遇到两个出栈的节点不相同,则这个节点的后一个节点就是第一个相交的节点。
3.遍历链表记录长度。
同时遍历两个链表到尾部,同时记录两个链表的长度。若两个链表最后的一个节点相同,则两个链表相交。
有两个链表的长度后,我们就可以知道哪个链表长,设较长的链表长度为len1,短的链表长度为len2。
则先让较长的链表向后移动(len1-len2)个长度。然后开始从当前位置同时遍历两个链表,当遍历到的链表的节点相同时,则这个节点就是第一个相交的节点。
4.哈希表法。
既然连个链表一旦相交,相交节点一定有相同的内存地址,而不同的节点内存地址一定是不同的,那么不妨利用内存地址建立哈希表,如此通过判断两个链表中是否存在内存地址相同的节点判断两个链表是否相交。具体做法是:遍历第一个链表,并利用地址建立哈希表,遍历第二个链表,看看地址哈希值是否和第一个表中的节点地址值有相同即可判断两个链表是否相交。
我们可以采用除留取余法构造哈希函数。
构造哈希表可以采用链地址法解决冲突。哈希表冲突指对key1 != key2,存在f(key1)=f(key2),链地址法就是把key1和key2作为节点放在同一个单链表中,这种表称为同义词子表,在哈希表中只存储同义词子表的头指针,如下图:
14. 一行代码实现数组去重?
[...new Set([1,2,3,1,'a',1,'a'])]
15. 怎么判断两个对象相等?
最开始的思路是遍历来判断,但是最后好像没有说清楚,查了下,好像可以转换为字符串来判断。
JSON.stringify(obj)==JSON.stringify(obj2);//trueJSON.stringify(obj)==JSON.stringify(obj3);//false
16. 项目做过哪些性能优化?
1、减少HTTP请求数
2、减少DNS查询
3、使用CDN
4、避免重定向
5、图片懒加载
6、减少DOM元素数量
7、减少DOM操作
8、使用外部JavaScript和CSS
9、压缩JavaScript、CSS、字体、图片等
10、优化CSS Sprite
11、使用iconfont
12、字体裁剪
13、多域名分发划分内容到不同域名
14、尽量减少iframe使用
15、避免图片src为空
16、把样式表放在 中
17、把脚本放在页面底部 欢迎补充。。。
17. 模块化开发是怎么做的?
使用命名空间。
18. Vue router 跳转和 location.href 有什么区别?
router是hash改变location.href是页面跳转,刷新页面
19. Set 和 Map 数据结构
ES6提供了新的数据结构Set它类似于数组,但是成员的值都是唯一的,没有重复的值。
ES6提供了Map数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说,Object结构提供了“字符串—值”的对应,Map结构提供了“值—值”的对应,是一种更完善的Hash结构实现。
20. 实现一个deepclone函数
function deepClone(obj) {
let objClone = Array.isArray(obj) ? [] : {};
if (obj && typeof obj === "object") {
for (key in obj) {
if (obj.hasOwnProperty(key)) {
//判断ojb子元素是否为对象,如果是,递归复制
if (obj[key] && typeof obj[key] === "object") {
objClone[key] = deepClone(obj[key]);
} else {
//如果不是,简单复制
objClone[key] = obj[key];
}
}
}
}
return objClone;
}
// 测试代码
let a = [1, 2, [1,5], 4],
b = deepClone(a);
a[0] = 2;
a[2][0] = 5;
console.log(a, b);
21. diff比较方式
22. vuex
23. cookie
24. computed methods watch
25. css js预加载
26. 实现继承的几种方式
27. 原型 原型链
28. 事件循环
29. 数组方法
30. 请求头 响应头