1.cookie和localStorage的区别
cookie:可设置失效时间,一般在浏览器关闭后失效;一般4k左右;每次都会携带在HTTP头中,如果使用cookie保存过多数据会影响性能。
localStorage:除非被清除,否则永久保存;一般5MB左右;仅在客户端(即浏览器)中保存,不参与和服务器通信。
sessionStorage:仅在当前会话下有效,页面或浏览器关闭就被清除;一般5MB左右;仅在客户端(即浏览器)中保存,不参与和服务器通信。
cookie由服务端生成,用于标识用户身份;而两个storage用于浏览器端缓存数据。
一般情况下浏览器端不会修改cookie,但会频繁操作两个storage。
安全性方面,cookie中最好不要放置任何明文的东西。两个storage的数据提交后在服务端一定要校验(其实任何payload和qs里的参数都要校验)。
2.如何做数组去重
第一种是比较常规的方法
思路:
1.构建一个新的数组存放结果
2.for循环中每次从原数组中取出一个元素,用这个元素循环与结果数组对比
3.若结果数组中没有该元素,则存到结果数组中
Array.prototype.unique1 = function(){
var res = [this[0]];
for(var i = 1; i < this.length; i++){
var repeat = false;
for(var j = 0; j < res.length; j++){
if(this[i] == res[j]){
repeat = true;
break;
}
}
if(!repeat){
res.push(this[i]);
}
}
return res;
}
var arr = [1, 'a', 'a', 'b', 'd', 'e', 'e', 1, 0]
alert(arr.unique1());
第二种方法比上面的方法效率要高
思路:
1.先将原数组进行排序
2.检查原数组中的第i个元素 与 结果数组中的最后一个元素是否相同,因为已经排序,所以重复元素会在相邻位置
3.如果不相同,则将该元素存入结果数组中
Array.prototype.unique2 = function(){
this.sort(); //先排序
var res = [this[0]];
for(var i = 1; i < this.length; i++){
if(this[i] !== res[res.length - 1]){
res.push(this[i]);
}
}
return res;
}
var arr = [1, 'a', 'a', 'b', 'd', 'e', 'e', 1, 0]
alert(arr.unique2());
第二种方法也会有一定的局限性,因为在去重前进行了排序,所以最后返回的去重结果也是排序后的。如果要求不改变数组的顺序去重,那这种方法便不可取了。
第三种方法(推荐使用)
思路:
1.创建一个新的数组存放结果
2.创建一个空对象
3.for循环时,每次取出一个元素与对象进行对比,如果这个元素不重复,则把它存放到结果数组中,同时把这个元素的内容作为对象的一个属性,并赋值为1,存入到第2步建立的对象中。
说明:至于如何对比,就是每次从原数组中取出一个元素,然后到对象中去访问这个属性,如果能访问到值,则说明重复。
Array.prototype.unique3 = function(){
var res = [];
var json = {};
for(var i = 0; i < this.length; i++){
if(!json[this[i]]){
res.push(this[i]);
json[this[i]] = 1;
}
}
return res;
}
var arr = [112,112,34,'你好',112,112,34,'你好','str','str1'];
alert(arr.unique3());
3.call和bind的区别
call和apply都是对函数的直接调用,而bind方法返回的仍然是一个函数,因此后面还需要()来进行调用才可以。
三者的相似之处:
都是用来改变函数的this对象的指向的。
第一个参数都是this要指向的对象。
都可以利用后续参数传参。
单个参数
对于call :xw.say.call(xh);
对于apply :xw.say.apply(xh);
对于bind :xw.say.bind(xh)();多个参数
对于call :xw.say.call(xh,"实验小学","六年级");
对于apply :xw.say.apply(xh,["实验小学","六年级"]);
call后面的参数与say方法中是一一对应的,而apply的第二个参数是一个数组,数组中的元素是和say方法中一一对应的,这就是两者最大的区别。那么bind可以像call那样传参。
xw.say.bind(xh,"实验小学","六年级")();
但是由于bind返回的仍然是一个函数,所以我们还可以在调用的时候再进行传参。
xw.say.bind(xh)("实验小学","六年级");
AJAX是什么,POST和GET的区别是什么
AJAX=异步JavaScript+XML
AJAX可以使页面实现异步更新。在不使页面整个重新加载的情况下,使网页局部更新。
get是向指定资源请求数据,是安全,幂等,可缓存,有长度限制的。
get是取数据,不需要带很大的数据量。把数据都放在url里面所以最好不要超过1024个字节,导致没有消息体,只有消息头。TCP对于这个就只发一个数据包。
post是向指定资源提交要被处理的数据,不是幂等,不可缓存,没有长度限制的。
post有消息体,得一个一个发。
语义的区别。
5.Promise怎么用
Promise是一个对象,用来传递异步操作。有以下两个特点
(1)对象的状态不受外界影响。Promise 对象代表一个异步操作,有三种状态:Pending(进行中)、Resolved(已完成,又称 Fulfilled)和 Rejected(已失败)。
(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise 对象的状态改变,只有两种可能:从 Pending 变为 Resolved 和从 Pending 变为 Rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。
var promise = new Promise(function(resolve, reject) {
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
promise.then(function(value) {
// success
}, function(value) {
// failure
});
Promise 构造函数接受一个函数作为参数,该函数的两个参数分别是 resolve 方法和 reject 方法。
如果异步操作成功,则用 resolve 方法将 Promise 对象的状态,从「未完成」变为「成功」(即从 pending 变为 resolved);
如果异步操作失败,则用 reject 方法将 Promise 对象的状态,从「未完成」变为「失败」(即从 pending 变为 rejected)。
6.var,let,const的区别
使用var声明的变量,其作用域为该语句所在的函数内,且存在变量提升现象;
使用let声明的变量,其作用域为该语句所在的代码块内,不存在变量提升;
使用const声明的是常量,在后面出现的代码中不能再修改该常量的值。
7.JSONP是什么
jsonp = json+padding
发一个请求,服务器根据请求参数返回js,js插入页面,被执行
例如我要从域A的页面pageA加载域B的数据,那么在域B的页面pageB中我以JavaScript的形式声明pageA需要的数据,然后在 pageA中用script标签把pageB加载进来,那么pageB中的脚本就会得以执行。
function getData(data){
//这里是对获取的数据的相关操作
console.log(data);
//数据获取到后移除创建的script标签
document.body.removeChild(originData);
}
var originData = document.createElement('script');
originData.src = 'http://www.jesse.com/data.js';
originData.setAttribute("type", "text/javascript");
document.body.appendChild(originData);
8.封装过哪些组件?有自己写过UI组件吗?
轮播组件