时间:2018.8.9 上午10:00-11:40
地点:北京朝阳区
-
面试题总结
1.浏览器原理?
主要分成两部分:渲染引擎(layout engineer或Rendering Engine)和JS引擎。
渲染引擎:负责取得网页的内容(HTML、XML、图像等等)、整理讯息(例如加入CSS等),以及计算网页的显示方式,然后会输出至显示器或打印机。浏览器的内核的不同对于网页的语法解释会有不同,所以渲染的效果也不相同。所有网页浏览器、电子邮件客户端以及其它需要编辑、显示网络内容的应用程序都需要内核。
JS引擎则:解析和执行javascript来实现网页的动态效果。
最开始渲染引擎和JS引擎并没有区分的很明确,后来JS引擎越来越独立,内核就倾向于只指渲染引擎。
2.js是单线程还是多线程?同步异步?浏览器同源策略?V8?
单线程,但是浏览器是多线程的,单线程的异步执行看下一题。
同步是指令发送一个请求,只有当请求完成之后才能发送下一个请求,需要等待时间。
而异步是指,指令发送一个请求,然后浏览器将这个请求放入到消息队列,你就可以关闭浏览器,或者发送下一个请求了。没有等待时间,用户体验性比较好。
但是并不是请求都是要用异步,在需要保存数据库操作过程的系统中需要用到同步,比如银行转账系统。
3.event loop(事件循环)
https://mdn.mozillademos.org/files/4617/default.svg
左边的栈存储的是同步任务,所谓同步的任务就是那些能立即执行、不耗时的任务,如变量和函数的初始化、事件的绑定等等那些不需要回调函数的操作都可归为这一类。右边的堆用来存储声明的变量、对象。下面的队列就是任务队列,一旦某个异步任务有了响应就会被推入队列中。如用户的点击事件、浏览器收到服务的响应和后面提到的setTimeout插入的事件。每个异步任务都和一个回调函数相关联。
一个js程序的单线程用来执行栈中的同步任务,当所有同步任务执行完毕后,栈被清空,然后读取任务队列中的一个待处理任务,并把相关回调函数压入栈中,单线程开始执行新的同步任务,执行完毕。
单线程从任务队列中读取任务是不断循环的,每次栈被清空后,都会在任务队列中读取新的任务,如果没有新的任务,就会等待,直到有新的任务,这就叫任务循环。因为每个任务都由一个事件所触发,所以也叫事件循环。
JavaScript单线程和其异步机制就如上所述。所谓的单线程并不孤单,它的背后有浏览器的其他线程为其服务,其异步也得靠其他线程来监听事件的响应,并将回调函数推入到任务队列等待执行。单线程所做的就是执行栈中的同步任务,执行完毕后,再从任务队列中取出一个事件(没有事件的话,就等待事件),然后开始执行栈中相关的同步任务,不断的这样循环。
除了放置异步任务的事件,"任务队列"还可以放置定时事件,即指定某些代码在多少时间之后执行。这叫做"定时器"(timer)功能,也就是定时执行的代码。
定时器功能主要由setTimeout()和setInterval()这两个函数来完成,它们的内部运行机制完全一样,区别在于前者指定的代码是一次性执行,后者则为反复执行。
4.静态资源服务器?
5.axios是什么?与Ajax有什么区别吗?
6.Ajax原理?调接口怎么调?callback怎么回调的?
xhr=new XMLHttpRequest();
xhr.onreadystatechange = callback;
xhr.open("Get",url,true);
xhr.send(null);
//上面代码中的req.send方法是Ajax操作向服务器发送数据,它是一个异步任务,
//意味着只有当前脚本的所有代码执行完,系统才会去读取"任务队列"。
function callback() {
//状态标识为已完成
if (xhr.readyState == 4) {
//已就绪
if (xhr.status <= 200 && xhr.status<300 || xhr.status == 304) {
console.log(xhr.responseText);
} else {
alert("There was a problem retrieving the XML data:" + xhr.statusText);
}
}
}
7.有一千个li,每一个都需要绑定事件,现在需要优化,你怎么做?事件委托有什么好处?
事件委托,事件冒泡
8.什么时候用到跨域?有哪些跨域方法?原理是什么?
jsonp的实现原理,跨域的其他方法
jsonp就是解决JSON跨域获取的解决方案,原理:
1、浏览器的同源策略把跨域请求都禁止了;
2、HTML的<script>标签是例外,可以突破同源策略从其他来源获取数据;
3、由上可得,我们可以通过<script>标签引入jsonp文件,然后通过一系列JS操作获取数据。
<button onclick="jsonpServer('jsonp.php')">JSONP</button>
function jsonpServer(url) {
var script = document.createElement("script");
script.setAttribute("src", url);
document.body.appendChild(script);
}
function JSON_CALLBACK(data) {
console.log(data);
}
<?php
header('Content-Type: application/javascript; charset=UTF-8');
$data = '[{"id":"1","name":"wsscat"},{"id":"2","name":"asw"}]';
$data = "JSON_CALLBACK(" . $data . ")";
echo $data;
?>
其他策略:
1.使用服务器代理实现跨域
2.document.domain
3.iframe
4.postMessage()
5.HTML5的websocket
6.浏览器在HTTP请求中添加Origin Header
作者:燕尾_三月
链接:https://www.jianshu.com/p/64818f53ee83
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
9.有用到哪些单位?新的单位有了解吗?calc(),vh,em,rem,in
em
做前端的应该对em不陌生,不是什么罕见的单位,是相对单位,参考物是父元素的font-size,具有继承的特点。如果字体大小是16px(浏览器的默认值),那么 1em = 16px。
不过,这样使用很复杂,很难很好的与px进行对应,因此,前端开发的前辈们总结了一个经验
body {
font-size: 62.5%;
}
那么,这样之后 1em = 10px 在布局等使用的时候好换算了很多。
百分比
百分比相信大家更不会陌生了,百分比一般宽泛的讲是相对于父元素,但是并不是十分准确。
- 1、对于普通定位元素就是我们理解的父元素
- 2、对于position: absolute;的元素是相对于已定位的父元素(offset parent)
- 3、对于position: fixed;的元素是相对于 ViewPort
viewport:可视窗口,也就是浏览器的window那么大。
rem
rem支持IE9及以上,意思是相对于根元素html(网页),不会像em那样,依赖于父元素的字体大小,而造成混乱。使用起来安全了很多。
html {font-size: 62.5%; /**10 ÷ 16 × 100% = 62.5% 1rem = 10px **/}
body {font-size: 1.4rem; /**1.4 × 10px = 14px **/}
h1 { font-size: 2.4rem; /**2.4 × 10px = 24px**/}
这样整个网页都会比较统一!不会造成混乱!
vh 和 vw
IE10+ 和现代浏览器都支持这两个单位。
vw Viewport宽度, 1vw 等于viewport宽度的1%
vh Viewport高度, 1vh 等于viewport高的的1%
vw和vh会随着viewport变化自动变化,再也不用js控制全屏了。
甚至有些人丧心病狂的字体大小都用vw和vh控制,来达到字体和viewport大小同步的效果。
ch和ex
IE9+ 和现代浏览器都已经支持,这两个单位时根据 当前font-family 的相对单位。
ch 字符0的宽度
ex 小写字符x的高度
css3的calc()
上面我们已经提到了calc(),下面我们就具体说一说吧!
浏览器支持IE9+、FF4.0+、Chrome19+、Safari6+
calc()语法非常简单,就像我们小时候学加 (+)、减(-)、乘(*)、除(/)一样,使用数学表达式来表示:
.haorooms {
width: calc(expression);
}
这样padding和margin和百分比一起用,问题就可以解决了。
例如,我们margin是20px。那么我们就可以写成
.haorooms{
width: calc(100% - 20px); //注:减号前后要有空格,否则很可能不生效!!
}
也可以这么用:
.box {
background: #f60;
height: 50px;
padding: 10px;
border: 5px solid green;
width: 90%;/*写给不支持calc()的浏览器*/
width:-moz-calc(100% - (10px + 5px) * 2);
width:-webkit-calc(100% - (10px + 5px) * 2);
width: calc(100% - (10px + 5px) * 2);
}
line-height百分比
line-height百分比在面试中可能经常问到。例如你知道line-height:120%和line-height:1.2的区别吗?
现在就说一下行高带单位和不带单位的区别,例如下面的例子:
line-height:26px; 表示行高为26个像素
line-heigth:120%;表示行高为当前字体大小的120%
line-height:2.6; 表示行高为当前字体大小的2.6倍
带单位的行高都有继承性
其子元素继承的是计算值,如父元素的字体大小为14px,定义行高line-height:2em;则计算值为 28px,不会因其子元素改变字体尺寸而改变行高。(例如:父元素14px,子元素12px,那么行高就是28px,子元素虽然字体是12px,行高还是父元素的行高)
不带单位的行高是直接继承
line-height:2.6;表示行高为当前字体大小的2.6倍
而不是计算值,如父元素字体尺寸为14px,行高line-height:2;子元素字体为12px,不需要再定义行高,他默认的行高为24px。(例如:子元素12px,他的行高是24px,不会继承父元素的28px)
10.布局定位,自己上黑板上写一下。
11.如何做优化?在js代码上的优化方案知道哪些?
12.模块化开发?
13.有哪些请求方式?除了post,get,两者的区别?
14.如何判断类型值?如何知道一个对象是什么类型?
我们都知道基本类型可以用typeof去判断,引用类型可以用instanceof去判断,但是这些判断的仅仅是是否的问题,那么我们怎么知道一个数据到底是什么类型呢?
接下来我们就用到另外一个利器:Object.prototype.toString.call
var gettype=Object.prototype.toString
gettype.call('aaaa') // [object String]
gettype.call(2222) // [object Number]
gettype.call(true) // [object Boolean]
gettype.call(undefined) // [object Undefined]
gettype.call(null) // [object Null]
gettype.call({}) // [object Object]
gettype.call([]) // [object Array]
gettype.call(function(){}) // [object Function]
//看到这里,刚才的问题我们解决了。
判断数据类型可以封装的方法如下 :
var gettype=Object.prototype.toString //toString() 方法可把一个逻辑值转换为字符串,并返回结果。
var utility={
isObj:function(o){
return gettype.call(o)=="[object Object]";
},
isArray:function(o){
return gettype.call(o)=="[object Array]";
},
isNULL:function(o){
return gettype.call(o)=="[object Null]";
},
isDocument:function(){
return gettype.call(o)=="[object Document]"|| [object HTMLDocument];
}
........
}
浏览器运行机制,还有浏览器内核,还有f12
js面向对象封装,继承,多态,this,原型