总结一下前端的面试经验,面试的太多了,就拿一些常问到的出来写一下吧,哈哈
1、事件流
事件发生时在元素节点与根节点之前按照特定的顺序传播,路径经过的所以节点都会受到该事件,这个传播过程即DOM事件流
有两种事件流模型:
冒泡型事件流:传播顺序即从内到外,(DOM树叶子到跟)是从最特定的事件到最不特定的事件。
捕获型事件流:从外向内捕获,(DOM树的跟到叶子) 从最不特定的目标到最特定的事件目标。
function Debounce(fn,Time){
let timer = null;
return function() {
if(timer){
clearTimeout(timer)
}
timer = setTimeout(fn,Time)
}
}
function showTop () {
var scrollTop = document.body.scrollTop ||
document.documentElement.scrollTop;
console.log('滚动条位置:' + scrollTop);
}
window.onscroll = Debounce(showTop,1000);
2、节流和防抖(debounce/throttle)
防抖和节流严格来说是属于性能优化的知识,遇到的频率还是很高的,还是有必要了解一下的。
(举个实际中会用到的案例吧)网站中大多数会提供一个返回顶部的按钮,运行的时候,你会发现,你定义的这个函数执行频率很高了,实际上用不上这么高频率的反馈,浪费资源。
这就是防抖的作用了。思路是触发事件是,不立刻执行函数,而是给与一个特点的期限如200ms,在200ms内没有再次触发滚动事件,就可以执行函数。如果200ms内再次触发时间的话,那么久重新计时。
(上面案例解决了,但是会出现一个问题,如果不断的触发事件(不断的滚动),只要一直触发事件,那么这个函数就导致了无法触发执行了)
所以就有了节流这个思路了。我们可以设置一种类似闸门的方法,由我们控制,在特点的事件后让函数执行。让其每隔一段时间自己输出一下。
//开关函数 闸门
function strobe(fn,Time){
let Boole = true;
return function() {
if(!Boole){
return false ;
}
Boole = false;
setTimeout(() => {
fn()
Boole = true;
}, Time)
}
}
//上下滑动
function showTop () {
var scrollTop = document.body.scrollTop ||
document.documentElement.scrollTop;
console.log('滚动条位置:' + scrollTop);
}
window.onscroll = strobe(showTop,1000);
3、如何解决跨域
跨域的解决方法还是很多的,我说下主流的俩种方法吧,一 后台通过设置请求头解决,(具体的我也没有了解),第二种就是前端通过jsonp的方式解决。动态创建script标签,使用jquert的jsonp请求。只能使用get方法,不能用post。
用script的scr属性实现,src | href他们没有被通源策略所限制(举了个小案例,仿百度搜索引擎)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<input type="search" name="" id="search" value="" />
<ul id="contents"></ul>
<script src="js/jquery-3.4.1.min.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
$("#search").keyup(function(){
var searchValue = $("#search").val();
if(!searchValue){
return false;
}
//1.创造keyup 事件的功能:把this目标var个变量,判断为空this,jsonp设置跨域,设置延迟器。2.定义调用函数功能:移除定时器,导到网页上
delay=setTimeout(function(){
$("#jsonp").remove();
var oscript = document.createElement("script");
oscript.src="https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd="+searchValue+"&cb=showData";
oscript.id = "jsonp";
$("body").append(oscript);
},400);
});
function showData(res){
clearTimeout(delay);
var $tempStr = "";
$.each(res.s,function(index,element){
$tempStr+="<li>"+element+"</li>";
});
$("ul").html($tempStr);
};
</script>
</body>
</html>
4、原型链
原型:每个对象都会在其内部初始化一个属性,就是prototype(原型)。
原型链:当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么他就会去prototype里找这个属性,这个prototype又会有自己的prototype,于是就这样一直找下去,也就是我们平时所说的原型链的概念。
所有实例对象需要共享的属性和方法,都放在这个对象里,实例对象一旦创建,将自动引用共享 propstype对象的属性和方法。
Prototype对象是实例对象的原型,而实例对象则好像继承了prototype对象
5、页面性能优化方面
1. 减少 HTTP 请求源
2. 减少 DNS 查找
3. 避免重定向
5. 延迟载入组件百
7. 减少 DOM 元素数量
9. 最小化 iframe 的数量
10.优化图片
11.图像格式的选择(GIF:提供的颜色较少,可用在一些对颜色要求不高的地方)
12.优化CSS(压缩合并css,如margin-top,margin-left...)
13.网址后加斜杠(如www.campr.com/目录,会判断这个“目录是什么文件类型,或者是目录。)
14.给图片设置宽高属性。
15.减少http请求(合并文件,合并图片)。
16.图标文字化
17. 使用 Ajax 缓存
18. 预先载入组件
19. 切分组件到度多个域
等。。。
6、Vue的响应式原理
vue的响应式核心是ES5的保护对象Object.defindeProperty的访问器属性get和set方法,data中声明属性会被添加访问器属性。当读取data中的数据时会调用get方法,修改data数据是会自己调用set方法。检测到数据变化后会通知观察者wacher,观察者自己触发render当前组件,就生成了新的DOM树,vue渲染时会新旧俩DOM树对比下,记录其中的差记录下来,最后加载,记录的不同点,修改到真正的DOM树上。
7、Promise
Promise是ES6中的异步编程解决方案,简单的来说就是一个容器,里面包含着未来才会结束的事件结果,
方法有很多种,then(),catch(),funally(),all(),care(),resolve(),reject();等
可以搭配async,await使用异步请求方案,请求可以通过try/actch来捕获异常。
这个我就不说这么多了,自己也没人认知那么多。一般面试官你给他说个大概,让他知道你会用,就可以了,可以举个例子,比如vue中的话 main.js中设置全局api, Vue.prototype.websiteUrl = '开发是的服务器前缀 后期上线直接改这里就可以了'
8、同步和异步的理解
同步,我理解是一种线性执行的方式,执行的流程不能跨越。一般用于流程性比较强的程序。
异步,是一种并行处理的方式,不必等待一个程序执行完,可以执行其它的任务。在程序中异步处理的结果通常使用回调函数来处理结果。在JavaScript中实现异步的方式主要有Ajax和H5新增的Web Worker。