混子前端分享一些面试常问干货,同时也帮助你们复习和巩固一波基础
ps:文章所有由我的总结,知识点分析不全面请自行查漏补缺javascript
假设高度已知,写出三栏布局,其中左栏/右栏宽度各为300px;中间自适应。css
(ps:此题做为一个小白也要至少答出3种方法,如下分享连混子前端都知道的5种方法)html
HTML部分:
<section class="layout float">
<article class='left-right-center'>
<div class="left"></div>
<div class="right"></div>
<div class="center"></div>
</article>
</section>
CSS部分:
.layout article div{
height: 100px;
}
.layout.float .left{
float: left;
width: 300px;
background: red;
}
.layout.float .right{
float: right;
width: 300px;
background: blue;
}
.layout.float .center{
background: yellow;
}
复制代码
HTML部分:
<section class="layout absolute">
<article class='left-right-center'>
<div class="left"></div>
<div class="center"></div>
<div class="right"></div>
</article>
</section>
CSS部分:.layout article div{
height: 100px;
}
.layout.absolute .left,.layout.absolute .right,.layout.absolute .center{
position: absolute;
}
.layout.absolute .left{
left: 0px;
width: 300px;
background: red;
}
.layout.absolute .right{
right: 0px;
width: 300px;
background: blue;
}
.layout.absolute .center{
left: 300px;
right: 300px;
background: yellow;
}
复制代码
HTML部分:
<section class="layout flexbox">
<article class='left-right-center'>
<div class="left"></div>
<div class="center"></div>
<div class="right"></div>
</article>
</section>
CSS部分:
.layout article div{
height: 100px;
}
.layout.flexbox .left-right-center{
display: flex;
}
.layout.flexbox .left{
width: 300px;
background: red;
}
.layout.flexbox .center{
flex: 1;
background: yellow;
}
.layout.flexbox .right{
width: 300px;
background: blue;
}
复制代码
HTML部分:
<section class="layout table">
<article class='left-right-center'>
<div class="left"></div>
<div class="center"></div>
<div class="right"></div>
</article>
</section>
CSS部分:
.layout article div{
height: 100px;
}
.layout.table .left-right-center{
width: 100%;
display: table;
height: 100px;
}
.layout.table .left-right-center>div{
display: table-cell;
}
.layout.table .left{
width: 300px;
background: red;
}
.layout.table .center{
background: yellow;
}
.layout.table .right{
width: 300px;
background: blue;
}
复制代码
HTML部分:
<section class="layout grid">
<article class='left-right-center'>
<div class="left"></div>
<div class="center"></div>
<div class="right"></div>
</article>
</section>
CSS部分:
.layout article div{
height: 100px;
}
.layout.grid .left-right-center{
display: grid;
width: 100%;
grid-template-rows: 100px;
grid-template-columns: 300px auto 300px;
}
.layout.grid .left{
background: red;
}
.layout.grid .center{
background: yellow;
}
.layout.grid .right{
background: blue;
}复制代码
补充:未知高度时,弹性盒flex / 表格table很适用,不修改代码前端
思考:上下高度固定,中间自适应(ps:混子前端都会的,你也必须会!)html5
你必须知道的盒子模型:
java
标准模型:不包含padding和border值,content即盒子width / heightweb
IE盒模型:盒子width / height包含padding和border值面试
box-sizing: content-box; // 标准盒模型(默认)
box-sizing: border-box; // IE盒模型复制代码
一、dom.style.width/height; // 获取内联样式宽/高[局限性]
二、dom.currentStyle.width/height; // 获取是渲染后的宽/高 [只有ie支持]三、window.getComputedStyle(dom).width/height; // 支持chrome、firefox
四、dom.getBoundingClientRect().width/height[left/right/top/bottom]; // 不多人知道,获取渲染后width/height,计算一个元素绝对位置,根据视窗(viewport),经常使用获取left/right/top/bottom复制代码
常见问题:子元素高度100px,margin-top: 10px,此时父元素高度 ?ajax
解:父元素是100px;若是父元素设置overflow: hidden,就是110px;算法
[就是给父元素建立BFC(块级格式化)]
基本概念:块级格式化上下文
原理(BFC渲染规则):
怎样建立BFC,除了给父元素添加overflow: hidden建立BFC,还有那些?
你必须知道几个关于DOM的知识点
一代:DOM 0级
element.onClick = function(){
// TODO
}复制代码
为何从DOM 0级直接到DOM 2级了?DOM 1级标准没有设定与事件相关的东西
二代:DOM 2级
element.addEventListener('click', function(){
// TODO
}, false);复制代码
三代:DOM 3级
新增了鼠标,键盘等事件
element.addEventListener('keyup', function(){
// TODO
}, false);复制代码
混子前端认为分为三个阶段:
捕获:window > document > HTML > body > HTML结构 > 一层层传递到目标元素
冒泡:捕获反过来就是冒泡,从目标元素传递到window
如:ul > li 点击触发,给ul绑定onclick方法,此时:
target:<li>
currentTarget:<ul>
var eve = new Event('custome'); // 声明自定义事件
ev.addEventListener('custome', function(){
console.log('custome');
});
ev.dispatchEvent(eve); // dispatchEvent api触发复制代码
补充:网站如今记住的是身份,不是http协议作到的,而是经过服务端加session作到的
客户端输入url,服务端响应;
报文分为2部分,即:请求报文 响应报文,如图所示:
GET:获取资源
POST:传输资源
PUT:更新资源
DELETE:删除资源
HEAD:得到报文首部
若是你对本身有追求,那如下你也要知道:
200:客户端请求成功
206:客户发送了一个带有Range头的GET请求,服务器完成;如:客户端发起0-10000字节请求,服务器返回206,服务端会根据Range头部截一部分,响应回客户端(客户端要求的Range范围)
301:所请求页面已经转移至新的url(永久重定向)
302:所请求页面已经临时转移至新的url(临时重定向)
304:客户端口有缓冲的文档并发出了一个条件性的请求,服务器告诉客户端,原来缓冲的文档还能够继续使用 [ 服务器告诉客户端有缓存,能够取缓存用,不用在服务器取 ]
400:客户端有语法错误,不能被服务器所理解
401:请求未经受权
403:对被请求页面访问禁止
404:资源不存在
500:服务器错误
503:服务器临时过载或宕机
HTTP协议采用“请求 -- 应答”模式,当使用普通模式,即非keep-alive(持久链接)时,每一个请求/应答客户端和服务器都要新建一个链接,完成以后当即断开链接(HTTP无链接协议)
当使用keep-alive模式(持久链接)时,keep-alive功能使客户端到服务端的链接持久有效,当出现对服务器的后续请求时,keep-alive功能避免了创建或者从新创建链接
注意:持久链接1.1版本才支持,1.0版本不支持
当使用持久链接的状况下,某个链接上消息的传递相似于:
请求1 > 响应1 > 请求2 > 响应2 > 请求3 > 响应3
某个链接上的消息变成了相似如下这样(管线化):
[请求1 > 请求2 > 请求3 ] > [响应1 > 响应2 > 响应3]
注意:
var o1 = {name: 'o1'};
var o11 = new Object({name: 'o11'});复制代码
var M = function(){this.name='o2'};
var o2 = new M();复制代码
var P = {name: 'o3'};
var o3 = Object.create(P)复制代码
Object.create()建立对象是用原型链链接的;o3的__proto__指向P对象,下文会说o3.__proto__指向构造函数的原型对象,也就是说原型就是P
o3.__proto__ === P; // true复制代码
ps:Object.create()方法是把参数中对象做为一个新对象原型对象赋给o3的,o3自己不具有name属性,是经过原型链链接它的原型对象;
ps:经过prototype 和 __proto__完成原型链向上找的过程,Object.prototype是整个原型链的顶端,到这里未知
问题来了:原型对象和原型链到底起什么做用?
解答:构造函数中增长不少属性和方法,实例就能够共用,当有不少个实例想去公用方法时,不可能每一个都拷贝一份,如今考虑应该有个东西存,这个东西就是原型对象
注意:
ps:主要在这条原型链上的构造函数都是实例对象构造函数
instanceof原理是 实例对象__proto__属性 和 构造函数 prototype判断是否是同一个引用,返回true / false
JS code:
function M (){ this.name = name };
var o = new M()
o instanceof M; // true
o instanceof Object; // true复制代码
注意为何 o instanceof Object 也返回true ?
JS code:
o.__proto__ === M.prototype; // true
M.prototype.__proto__ === Object.prototype; // true复制代码
JS code:
o.__proto__.constructor === M; // true
o.__proto__.constructor === Object; // false复制代码
因此说使用constructor判断比instanceof更严谨
JS code:
var newF = function(func){
var o = Object.create(func.prototype); // 1.建立对象关联构造函数原型对象
var k = func.call(o); // 2.执行构造函数
if(typeof k === 'object'){ // 3.判断构造函数运行结果,是否为对象类型
return k;
}else{
return o;
}
}复制代码
源:协议 / 域名 / 端口 80(默认),这三个有一项不一样就跨域了
限制:不是同一个源文档没有权利修改另外一个源文档
var xhr = XMLHttpRequest ? new XMLHttpRequest() : new Window.ActiveXObject("Microsoft.XMLHTTP"); // 兼容写法
xhr.setRequestHeader(); // header头部信息
xhr.open("GET","/try/ajax/ajax_info.txt", true);
xhr.send(); // 发送
// xhr.onload判断xhr.status = 200 || 206 || 304 复制代码
Ajax是不能发送跨域通讯的,浏览器在识别用Ajax发送一个跨域请求时,它会在http头部加origin来容许跨域通讯,若是不加就被拦截,这也是前端混子所理解CORS原理
JSONP
原理:在出现postMessage和CORS前,用script标签的异步加载实现;
JS code:
// 发送
<script src="http://www.abc.com/?data=name&callback=jsonp"></script>
// 返回
<script>
jsonp({
data:{}
}) </script>
// 发送
document.getElementByTagName('head')[0].appendChild('script');复制代码
实现:
1.告诉服务端callback名称,未来是做为函数名返回的
2.本地必须有jsonp全局函数,后面才能把数据执行出来
Hash
应用场景:页面A经过iframe潜入跨域页面B并发送消息
var B = document.getElementByTagName('iframe');
B.src = B.src + '#' + 'data';
window.onhashchange = function(){ // 写在B页面中, 监听hash有没有改变
var data = window.location.hash;
}复制代码
postMessage
应用场景同上
// A页面发送到B
B.window.postMessage('data', 'http://B.com');
// B页面接收A
window.addEventListener('message',function(event){
console.log(event.origin); // 拿到A的源
console.log(event.source); // Awindow的对象
console.log(event.data); // 发送的消息拿到了
}, false);复制代码
Websocket
var ws = new Websocket('wss: echo.websocket.org'); // 指向服务器地址, ws不加密, wss加密
ws.onopen = function(){ ws.send(); }; // 发送出去
ws.onmessage = function(ev){
ev.data;
ws.close; // close断开
}复制代码
CORS
新型的Ajax通讯api:fetch 实现CORS通讯
fetch('/some/url',{
method: 'get'
}).then(function(response){
}).catch(function(error){
});复制代码
CSRF:称为跨站请求伪造
ps:引诱点击后访问网站A后,浏览器自动上传cookie,A网站对身份从新确认(合法),就执行了动做,完成CSRF攻击
实现CSRF不可缺乏的条件:
CSRF防护措施:
XSS称为跨域脚本攻击
攻击原理:不须要作登录验证,核心原理是向页面注入脚本 [ 评论区是最好最入css攻击的,在提交区里面写script标签,img标签等 ],xss是利用合法渠道注入JS
防护措施:宗旨是不让页面执行插入的JS脚本
XSS与CSRF对比区别
你要知道的:DTD(document type definition)告诉浏览器我是什么类型,浏览器根据类型来判断用什么引擎优化它;如:XML / HTML
这里是做用:DOCTYPE是声明文档类型和DTD规范的,直接告诉浏览器当前文档包含哪些DTD(文档类型)
<!DOCTYPE HTML> // html5
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//en" "http://www.w3. org/TR/html4/strict.dtd"> // HTML4严格:不包含展现性和弃用元素(front)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//en" "http://www.w3. org/TR/html4/loose.dtd"> // HTML4传统:包含展现性和弃用元素(front)
复制代码
浏览器根据各类样式计算放在它该出现的问题,如:JS修改div中内容(即触发Reflow)
常见触发Reflow
屏幕上页面的呈现内容
常见触发Repaint
JS是单线程的(同一事件只能作一件事);这里混子前端拿道面烂了的面试题来举例:
JS代码:
for (var i = 1;i <= 5;i ++) {
setTimeout(function timer() {
console.log(i)
},i * 1000)
}复制代码
对JS做用域、闭包以及事件循环等概念不了解的伙伴会想固然的回答:
第一次循环,隔一秒输出1;
第二次循环,隔一秒输出2;
第三次循环,隔一秒输出3;
第四次循环,隔一秒输出4;
第五次循环,隔一秒输出5;
或者还有伙伴预期结果是分别输出数字1~5,每秒依次,每次一个。
但实际结果你们粘贴到控制台就都知道,以一秒的频率输出五个6。
下面来过一下上面提到的知识点:
做用域:这里我引用《你不知道的javascript》中的一个比喻,能够把做用域链想象成一座高楼,第一层表明当前执行做用域,楼的顶层表明全局做用域。咱们在查找变量时会先在当前楼层进行查找,若是没有找到,就会坐电梯前往上一层楼,若是仍是没有找到就继续向上找,以此类推。到达顶层后(全局做用域),可能找到了你所需的变量,也可能没找到,但不管如何查找过程都将中止。
闭包:个人理解是在传递函数类型的变量时,该函数会保留定义它的所在函数的做用域。读起来可能比较绕,或者能够简单的这么理解,A函数中定义了B函数而且它返回了B函数,那么无论B函数在哪里被调用或如何被调用,它都会保留A函数的做用域。
事件循环:这个概念深刻起来很复杂,下面新开一个段落详谈:
提及事件循环,不得不提起任务队列。事件循环只有一个,但任务队列可能有多个,任务队列可分为宏任务(macro-task)和微任务(micro-task)。
XHR回调、事件回调(鼠标键盘事件)、setImmediate、setTimeout、setInterval、indexedDB数据库操做等I/O以及UI rendering都属于宏任务(也有文章说UI render不属于宏任务,目前尚未定论)
process.nextTick、Promise.then、Object.observer(已经被废弃)、MutationObserver(html5新特性)属于微任务。注意进入到任务队列的是具体的执行任务的函数。
好比上述例子setTimeout()中的timer函数。另外不一样类型的任务会分别进入到他们所属类型的任务队列,好比全部setTimeout()的回调都会进入到setTimeout任务队列,全部then()回调都会进入到then队列。当前的总体代码咱们能够认为是宏任务。事件循环从当前总体代码开始第一次事件循环,而后再执行队列中全部的微任务,当微任务执行完毕以后,事件循环再找到其中一个宏任务队列并执行其中的全部任务,而后再找到一个微任务队列并执行里面的全部任务,就这样一直循环下去。这就是我所理解的事件循环。
继续看个栗子:
JS代码:
console.log('global')
setTimeout(function () {
console.log('timeout1')
new Promise(function (resolve) {
console.log('timeout1_promise')
resolve()
}).then(function () {
console.log('timeout1_then')
})
},2000)
for (var i = 1;i <= 5;i ++) {
setTimeout(function() {
console.log(i)
},i*1000)
console.log(i)
}
new Promise(function (resolve) {
console.log('promise1')
resolve()
}).then(function () {
console.log('then1')
})
setTimeout(function () {
console.log('timeout2')
new Promise(function (resolve) {
console.log('timeout2_promise')
resolve()
}).then(function () {
console.log('timeout2_then')
})
}, 1000)
new Promise(function (resolve) {
console.log('promise2')
resolve()
}).then(function () {
console.log('then2')
})
复制代码
来一步一步分析以上代码:
再回过头来看上面那个问题,理解了事件循环的机制,问题就很简单了。for循环时setTimeout()不是当即执行的,它们的回调被push到了宏任务队列当中,而在执行任务队列里的回调函数时,变量i早已变成了6。那如何获得想要的结果呢?很简单,原理就是须要给循环中的setTimeout()建立一个闭包做用域,让它执行的时候找到的变量i是正确的。
混子前端给出以下5种解决方案:
JS代码
for(var i = 0;i < 5; i++){
(function(i){
setTimeout(function timer(){
console.log(i);
}, i * 1000)
})(i);
}
复制代码
JS代码
for(let i = 0;i<5;i++) {
setTimeout(function timer(){
console.log(i);
}, i * 1000);
}
复制代码
利用ES 5引入的bind函数
JS代码
for (var i=1; i<=5; i++) {
setTimeout( function timer(i) {
console.log(i);
}.bind(null,i), i*1000 );
}
复制代码
利用setTimeout第三个参数
JS代码
for (var i=1; i<=5; i++) {
setTimeout(function timer(i) {
console.log(i);
}, i*1000,i );
}
复制代码
把setTimeout用一个方法单独出来造成闭包
JS代码
var loop = function (i) {
setTimeout(function timer() {
console.log(i);
}, i*1000);
};
for (var i = 1;i <= 5; i++) {
loop(i);
}复制代码
<meta http-equiv="x-dns-prefetch-control" content="on">
<link rel="dns-prefetch" href="//host_name_to_prefetch.com">复制代码
首先咱们要知道错误分类:
(一)若是是即时性错误
(二)若是是资源加载性错误
JS代码
window.addEventListener('error', function(){
// ****
}, true);复制代码
ps:若是JS错误是跨域的,能够在script标签添加crossorigin属性,同时在响应JS资源时,设置JS资源头Access-Control-Allow-Origin就能够拿到错误信息了
这里上报错误的原理:利用ajax通信上报 / 也能够利用image对象上报
JS代码
(new Image()).src = "http://baidu.com/tesjk?r=tksjk";复制代码
利用这种方式比ajax简单,也能实现资源上报
因为本人也是混子前端,不一一列举,但做为一名合格的前端,算法是必不可少的。
ps:请随意吐槽本混子,会虚心接受
好了,混子前端就总结到这里,还请留意混子前端不定时的更新....