1.本地存储(local storage、session storage)和cookie之间的区别?
1.seesionStorage 用于本地存储一个临时会话数据,这些数据只有在同一个会话页面才能访问,当页面关闭,数据也随之销毁。
2.localStorage 用于永久性本地存储,除非主动删除,不然数据会一直存在。
3.本地存储:只有本地浏览器端可以访问数据,服务器不能访问本地存储直到通过post或get发送数据到服务器。
4.cookie:服务器和客户端都可以访问,大小只有4kB左右,有有效期,过期会自动删除。
cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下。cookie数据不能超过4k,同时因为每次http请求都会携带cookie,所以cookie只适合保存很小的数据
2.简述一下 src 与 href 的区别?
src指向外部资源的位置,指向的内容将会嵌入到文档中当前标签所在的位置,在请求src资源时会将其指向的资源下载并应用到文档内,例如js脚本/img图片/frame等元素。
href用于在当前文档中和引用资源之间确立关系。
注:src引入时,当浏览器解析到该元素,会暂停其他元素的下载和处理,直到将该资源加载、编译、执行完毕。所有一般建议将src引入文件放在底部而不是头部。
3.json 的了解
json是一种轻量级的数据交换格式。它是基于javascript的一个子集。数据格式简单,易于读写,占用带宽少。
4.jsonp的原理
通过<script>标签的src属性并不被同源策略所约束来实现跨域访问,
同源策略所谓的同源指的是域名、协议、端口、相同
与AJAX的区别是什么?
ajax和jsonp本质上是不同的东西。
ajax的核心是通过XmlHttpRequest获取非本页内容
jsonp的核心则是动态添加<script>标签来调用服务器提供的js脚本。
5.document.write 和 innerHTML 的区别?
document.write是对整个页面的重写,写入的内容是字符串的html;
innerHTML 是HTMLElement的属性,是一个元素的内部html内容
var zzz= document.getElementById('aaa')
zzz.innerHTML="xiaoxin"
document.write('<h2>我是h2</h2>')//docment.write可以识别标签
6.什么是箭头函数
箭头函数就是使用(=>)定义函数的新语法,有以下特征:
1.不能通过new关键字调用
2.没有原型(因为不能通过new调用)
3.没有this的绑定,箭头函数中的this指向它的外层非箭头函数this的指向
4.没有arguments对象,但是可以获取到外层函数的arguments
5.call,apply,bind不能改变this的指向
定时器中的this指向window
在JavaScript中,arguments对象是比较特别的一个对象,实际上是当前函数的一个内置属性。arguments非常类似Array,但实际上又不是一个Array实例。
function f(a, b, c){
alert(arguments.length); // result: "2"
a = 100;
alert(arguments[0]); // result: "100"
arguments[0] = "qqyumidi";
alert(a); // result: "qqyumidi"
alert(c); // result: "undefined"
c = 2012;
alert(arguments[2]); // result: "undefined"
}
f(1, 2);
6.懒加载实现的原理
设置当用户浏览到当前资源的时候,或者触发某一事件,在对页面进行请求加载。
1.我们可以利用监听事件回调来实现懒加载
2.使用定时器实现懒加载
7.定时器
定时器中的this指向window
setInterval() :按照指定的周期(以毫秒计)来调用函数或计算表达式。方法会不停地调用函数,直到 clearInterval() 被调用或窗口被关闭。
setTimeout() :在指定的毫秒数后调用函数或计算表达式。
8. for循环 / for in循环/ 和 for of 循环 的区别?
var arr = [1,5,6];
arr.length = 10;
arr[12] = 16;
arr[15] = 20;
console.log(arr)
// --------------------------------------------
// for 循环,循环数组中所有数据包括空undefine
for ( var i=0; i<arr.length; i++){
console.log(arr[i]) // 1 5 6 undefine*9 16 undefine*2 20
}
// ---------------------------------------------
// for in 循环,可以遍历数组的索引,和遍历数组中不为空的数据
for (var j in arr){
console.log(j)// 0 1 2 12 15
}
for (var j in arr){
console.log(arr[j]) // 1,5,6,16,20
}
// --------------------------------------------------
// for of 循环,遍历数组中数据,跟for循环一样
for (var k of arr){
console.log(k) //1 5 6 undefine*9 16 undefine*2 20
}
9.map/set/foreach/数组的增删改查 /数组的扁平化
10.数组的去重
1.ES6中的set方法去重
// Array.from()方法可以将 Set 结构转为数组
let newArray = Array.from(new Set(oldarr));
2.index of 方法去重,index of 查找值,如果没找到就返回-1,找到了就返回匹配到的第一个索引值
通过for循环遍历数组,然后就遍历的值一个个的拿到数组中去比较如果索引值为-1表示没有重复的数据就添加至新数组
for(let i=0; i<oldarr.length; i++){
if(newarr.indexOf(oldarr[i]) === -1 ){
newarr.push(oldarr[i]);
}
}
3.Filter 方法,返回所有通过测试的内容,也利用了index of特性
通过Filter方法将老数组里面的数据一个个的和老数组比较,如果索引值相同就添加到新数组,
因为index of返回的是第一个索引值,如果不同表示重复了
let newarr2 =[];
newarr2 = oldarr.filter((item,index) => oldarr.indexOf(item) === index)
console.log(newarr2);
4.sort 方法 //将数组进行sort排序,将第一个元素和第二个元素比较,不一样就加入
let newarr3 = [];
oldarr = oldarr.sort();
newarr3.push(oldarr[0]);
for(let j =1; j<oldarr.length; j++){
// if( oldarr[j] !== oldarr[j-1]){
// newarr3.push(oldarr[j]);
// }
oldarr[j] !== oldarr[j-1] && newarr3.push(oldarr[j])
}
console.log(newarr3);
11. 谈谈浏览器的内核,和什么是内核
谷歌和safari——webkit
IE——trident
浏览器内核分为2个部分:渲染引擎和JS引擎
12.什么是BFC
块级格式化上下文
13.垃圾回收机制的了解
JavaScript的解析器可以检测到何时程序不再使用一个对象了,当他确定了一个对象是无用的时候,他就知道不再需要这个对象,可以把它所占用的内存释放掉了。闭包函数内调用函数可以保留函数的执行站,不被垃圾回收机制回收。
14. canvas 标签进行图形绘制。元素本身并没有绘制能力(它仅仅是图形的容器) - 必须使用脚本来完成实际的绘图任务。
html:
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">
</canvas>
js:
//绘制矩形
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.fillStyle="#0000ff";
ctx.fillRect(20,20,150,100);
//绘制曲线
ctx.beginPath();
ctx.lineWidth="5";
ctx.strokeStyle="red"; // 红色路径
ctx.moveTo(0,75);
ctx.lineTo(250,75);
ctx.stroke(); // 进行绘制
//绘制内容/字体/大小
ctx.font="40px Arial";
ctx.fillText("Hello World",50,150);//后面2位参数决定了内容距离左边的距离和上面的距离
15.移动端300ms延迟解决方案
1. faskclick
- 原理: 在检测到touchend事件的时候,会通过DOM自定义事件立即出发模拟一个click事件,并把浏览器在300ms之后真正的click事件阻止掉
- 缺点: 脚本相对较大, 不建议使用
2. 禁用浏览器缩放
3. 更改默认的视口宽度
浏览器就可以认为该网站已经对移动端做过了适配和优化,就无需双击缩放操作了。
4.通过 touchstart 和 touchend模拟实现
能不能直接用touchstart代替click呢,
答案是不能,使用touchstart去代替click事件有两个不好的地方。
第一:touchstart是手指触摸屏幕就触发,有时候用户只是想滑动屏幕,却触发了touchstart事件,这不是我们想要的结果;
第二:使用touchstart事件在某些场景下可能会出现点击穿透的现象。
什么是点击穿透?
假如页面上有两个元素A和B。B元素在A元素之上。我们在B元素的touchstart事件上注册了一个回调函数,该回调函数的作用是隐藏B元素。我们发现,当我们点击B元素,B元素被隐藏了,随后,A元素触发了click事件。
这是因为在移动端浏览器,事件执行的顺序是touchstart > touchend > click。而click事件有300ms的延迟,当touchstart事件把B元素隐藏之后,隔了300ms,浏览器触发了click事件,但是此时B元素不见了,所以该事件被派发到了A元素身上。如果A元素是一个链接,那此时页面就会意外地跳转
16.对同一个对象绑定多个响应事件并都执行
因为 onclick=" " 添加的元素响应事件,先添加的事件,会被后来添加的事件层叠掉,只能执行最后一个响应的事件
所以要用到事件监听addElementLitener()来绑定多个处理函数
addEventListener(myGet("btn"),"click",function () {
console.log("111");
});
addEventListener(myGet("btn"),"click",function () {
console.log("222");
});
addEventListener(myGet("btn"),"click",function () {
console.log("3333");
-
模块化开发的理解
commonJS规范 import export default amd requied.js
-
post , get区别
安全
速度
提交方式 三次握手
18.var let 区别
var声明的是全局变量
let声明的是局部变量,块级作用域,会造成暂时性死区,不能重复声明,不会变量提升。
19. JS哪些操作会造成内容泄露
- 意外的全局变量引起的内存泄露
- 闭包引起的内存泄露
- 没有清理定时器
- 业务逻辑有问题造成的死循环
20js执行环境,js运行原理
21.移动端一像素问题解决方案
我们公司之前常用的是一个封装好的scss库,解决了一像素的问题。
我们也可以用媒体查询结合transform来解决,先使用媒体查询,屏幕的比例,然后transform 进行缩放。
22.vue1.0和vue2.0的主要区别
我开始了解vue的时候已经是vue2.0版本了,所有对vue1.0没有过多的了解,不过我知道1.0和2.0一个很大的改动就是生命周期的改动,2.0生命周期做了很大的优化。(17年始接触2.0,2.0大概是16年5月出来的)
23.怎么理解webpack打包 底层原理
24 map 和 set的区别
Set是无重复值的有序列表。Set会自动移除重复的值,
Map是有序的键值对,其中的键允许是任何类型。
他们功能都比较类似对对象进行快速遍历。
25 浏览器缓存原理
26.200 304 404 500
27.谈谈对Promise/Generator/async await的理解
简单的来说,promise就是一个容器,它里面存放着一个未来才会结束的时间的结果,从语义上来说,它就是一个JavaScript对象,是解决异步编程的一种方法,执行成功会执行对应的函数,失败会执行失败对应的函数。
Generator是ES6提供的一种异步编程的解决方案。它的语法行为与传统函数完全不同。执行generator函数会返回一个遍历器对象,可以依次遍历Generator函数内部的每一个状态。
async await 就是Generator函数的语法糖。它使用起来更加方便、简单。
8-11面试题
1.如何优化SPA首屏加载慢的问题
- 模块化开发
- 利用懒加载技术
- 抽取css文件
- 预渲染(不依赖数据,骨架结构)
- gulp代码压缩
2.vue 服务端渲染( SSR)的理解
Vue.js 是构建客户端应用程序的框架。默认情况下,可以在浏览器中输出 Vue 组件,进行生成 DOM 和操作 DOM。然而,也可以将同一个组件渲染为服务器端的 HTML 字符串,将它们直接发送到浏览器,最后将这些静态标记"激活"为客户端上完全可交互的应用程序。
服务器渲染的 Vue.js 应用程序也可以被认为是"同构"或"通用",因为应用程序的大部分代码都可以在服务器和客户端上运行。
服务端渲染
- 更好的 SEO。
- 更快的内容到达时间 ,用户将会更快速地看到完整渲染的页面
- 服务器端渲染 (SSR) 可以帮助你实现最佳的初始加载性能。
- 更多的服务器端负载。
3. Vue依赖注入的理解
当嵌套组件的层级较深时,我们的父级组件无法很好的将数据和方法提供给后代组件。此时我们可以使用依赖注入,它用到两个新的实例选项:provide和inject
`provide` 选项允许我们指定我们想要**提供**给后代组件的数据/方法。
然后在任何后代组件里,我们都可以使用 `inject` 选项来接收指定的我们想要添加在这个实例上的属性
然而,依赖注入还是有负面影响的。它将你应用程序中的组件与它们当前的组织方式耦合起来,使重构变得更加困难。同时所提供的属性是非响应式的。
如果你想要共享的这个属性是你的应用特有的,而不是通用化的,或者如果你想在祖先组件中更新所提供的数据,那么这意味着你可能需要换用一个像 Vuex 这样真正的状态管理方案了。
8-13
1.常见的居中方案
水平:margin: 0 auto;
垂直已知元素宽高:
1.定位top50%,left50%,减去自身宽高的一半
未知自身的宽高:
2.弹性盒布局:justify-content: center; align-item: center
3.基线对齐:写一个空的span的设置为行内块元素,高度100%,vertical-align:middle,未知元素也设置基线居中对齐。
4.表格居中对齐:父元素设置display:table;子元素设置table-cell;然后vertical-align:middle基线居中对齐
5.固定定位:position:fixed; top:0;left:0;right:0;bottom:0; margin:auto;