JavaScript前端面试
系列文章:
HTML及HTTP面试笔试题
CSS面试笔试题
JS一些算法题:
FE-interview-questions,满意点个star。(待更新)
0. 序
本文没有太多基础性的js内容,推荐一本书《JavaScript高级程序设计》,基础不好的同学建议先学习该本书。重点内容:事件,闭包,作用域练,原型,继承。
1.情简述一下javascript的执行环境(执行上下文)以及所涉及到到一些概念?(该文的整体笔记丢失,详细内容建议查看引用链接)
每当控制器转到可执行环境时,就会进入一个执行环境。
而执行环境大致分为三类:
- 全局环境
- 函数环境
- eval(个人不了解,开发也不会用到不做讲解)
执行环境是靠栈来存储,每当开始执行js代码的时候,就进入到了全局执行环境,于是乎,就把全局执行环境压到了这个栈(我们暂时称它为执行环境栈)中。
而在全局代码中,会定义很多函数,函数中又会定义很多函数,而每当控制器执行到函数时,则就进入到了这个函数的执行环境中。
http://www.jianshu.com/p/cd3fee40ef59
2.sessionStorage,localStorage,cookie区别
- 共同点:都是浏览器端的数据存储,同源;
- 不同点:
- cookie在同源的http请求中携带,浏览器与服务器之前回传。cookie有路径的概念;cookie大小不超过4k。
- sessionStorage(浏览器关闭窗口前有效)和localStorage(一直有效)达到5M或者更大。
- cookie在设置的有效期前有效
- session不在不同的浏览器窗口中共享,loacl共享,cookie也共享。
- sessionStorage和localStorage支持事件机制
3.localStorage应该如何进行存储?
// 将数据存在loaclStorage中
export function saveToLocal(id, key, value) {
let seller = window.localStorage.__seller__;
if (!seller) {
seller = {};
seller[id] = {};
} else {
seller = JSON.parse(seller);
if (!seller[id]) {
seller[id] = {};
}
}
seller[id][key] = value;
window.localStorage.__seller__ = JSON.stringify(seller);
};
export function loadFromLocal(id, key, def) {
let seller = window.localStorage.__seller__;
if (!seller) {
return def;
}
seller = JSON.parse(seller)[id];
if (!seller) {
return def;
}
let ret = seller[key];
return ret || def;
};
4.GET与POST的区别?
- GET与POST都是HTTP协议中的请求发送方式,实际上他们都是TCP,所能做的事情都是一样的。
- 不同在于,HTTP规定,发送GET请求时,在HTTP Header的请求行上就声明GET,反之POST就声明POST。
- HTTP要求,GET把数据放在url上,所以GET常用于发少量的数据用于查询;POST把数据放在body中,数据量相对较大用来存储。
- GET请求只发一次,POST发两次,header返回后再发送date。
5.同源策略指的是什么?
- 同源指的是以下三个都相同:
- 协议相同
- 域名相同
- 端口相同
- 所谓同源策略指的是:浏览器对不同源的脚本或者文本的访问方式进行的限制。比如源a的js不能操作引入的源b的元素属性。
- 限制主要为:
- Cookie、LocalStorage 和 IndexDB 无法读取。
- DOM无法获取
- AJAX请求不能发送
6.如何才能跨域,跨域方式有哪些?
- 设置document.domain
Cookie是服务器写入浏览器的一小段信息,只有同源的网页才能共享。但是,两个网页的一级域名相同,只是二级域名不相同,浏览器允许通过设置document.domain共享Cookie。
在 www.a.com/a.html 中
document.domain = 'a.com';
var ifr = document.createElement('iframe');
ifr.src = 'http://www.script.a.com/b.html';
ifr.display = none;
document.body.appendChild(ifr);
ifr.onload = function(){
var doc = ifr.contentDocument || ifr.contentWindow.document;
// 这里就能b.html的cookie了
ifr.cooike = doc.cookie;
};
在 script.a.com/b.html 中
document.cookie = "test1=hello";
document.domain = 'a.com';
这样不仅能访问b的cookie,还可以访问b的dom,但是无法访问到LocalStorage 和 IndexDB,而且主要限制是a,b必须一级域名必须相同。
- window.name
浏览器窗口都有window.name这个属性,这个属性最大的特点是,无论是否同源,只要在同一个窗口里,前一个网页设置了这个属性,后一个网页就可以读取它。
在b.com/data.html中有这样的数据
现在a.com/index.html想获取这个数据应该怎么办?通过iframe充当中间人
些人可能会问为什么不直接把iframe的src设置为目的源(b.com/data.html)来获取数据,而是在设置为目的源之后,还要把src设置为同域名下的其他源(a.com/b.html)才获取数据?
如果直接设置src,那么iframe和本网页(a.com/index.html)会因为同源策略限制不能访问。而把iframe先设置为目的源,再设置为同域名下的其他源,那么同域名下的其他源就和目的源共享了一个窗口,故拥有同样window.name,并且由于是同域名下的源,并且设置了domain,故可以访问目标源的window.name。
state用来干什么 ?
每次设置src,都会刷新,state是标志位,让获取了数据就销毁掉。
- window.postMessage
上面的方法都是破解,H5提供了官方的API:window.postMessage。允许跨窗口通信,不论这两个窗口是否同源。
// 举例来说,父窗口http://aaa.com向子窗口http://bbb.com发消息,调用postMessage方法就可以了。
var popup = window.open('http://bbb.com', 'title');
popup.postMessage('Hello World!', 'http://bbb.com');
postMessage方法的第一个参数是具体的信息内容,第二个参数是接收消息的窗口的源(origin),即"协议 + 域名 + 端口"。也可以设为*,表示不限制域名,向所有窗口发送。
// 子窗口向父窗口发送消息的写法类似。
window.opener.postMessage('Nice to see you', 'http://aaa.com');
// 父窗口和子窗口都可以通过message事件,监听对方的消息。
window.addEventListener('message', function(e) {
console.log(e.data);
},false);
// event.source:发送消息的窗口
// event.origin: 消息发向的网址
// event.data: 消息内容
下面的例子是,子窗口通过event.source属性引用父窗口,然后发送消息。
window.addEventListener('message', receiveMessage);
function receiveMessage(event) {
event.source.postMessage('Nice to see you!', '*');
}
- AJAX
利用jsonp
// 首先,网页动态插入