JS前端面试问答(二)

1.对于前端的事件流,你是怎么理解的?

答:事件流是浏览器中页面接收到事件的顺序,从最外层的元素到最里层的元素为事件捕获流(如html>body>div),从最里层元素传到最外层元素是事件冒泡流(如div>body>html)。开发中建议使用事件冒泡,因为容易理解,阻止冒泡等。

2.简要介绍下事件委托并举个例子,使用事件委托有什么好处?

(1)事件委托即利用事件冒泡机制指定一个事件处理程序,管理事件委托元素下的所有元素事件。
(2)如给ul父元素添加事件,li元素被点击后,ul父元素可监听到li元素被点击。
(3)使用事件委托的好处是节省内存并减少DOM操作。

3.使用图片懒加载和预加载的区别,原理和优缺点?

(1)图片预加载与懒加载的区别:
两者的行为是相反的,一个是提前加载,一个是迟缓甚至不加载。
(2)图片预加载和懒加载的原理和优缺点
图片预加载:在网页全部加载之前,提前加载图片。当用户需要查看时可直接从本地缓存中渲染,以提供给用户更好的体验,减少等待的时间。否则,如果一个页面的内容过于庞大,没有使用预加载技术的页面就会长时间的展现为一片空白,这样浏览者可能以为图片预览慢而没兴趣浏览,把网页关掉,这时,就需要图片预加载。当然这种做法实际上牺牲了服务器的性能换取了更好的用户体验。
图片懒加载:延迟加载图片或符合某些条件时才加载某些图片。这样做的好处是减少不必要的访问数据库或延迟访问数据库的次数,因为每次访问数据库都是比较耗时的即只有真正使用该对象的数据时才会创建。懒加载的主要目的是作为服务器前端的优化,减少请求数或延迟请求数。懒加载对服务器前端有一定的缓解压力作用,预载则会增加服务器前端压力。

4.mouserover和mouseenter的区别?

答:mouseenter不会触发事件冒泡。

5.clientHeight,scrollHeight,offsetHeight,以及scrollTop,offsetTop,clientTop的区别?

(1)clientHeight:包括padding但不包括border、水平滚动条、margin的元素的高度。对于inline的元素这个属性一直是0,单位px,只读元素。clientHeight=padding+height-横向滚动轴高度。
(2)offsetHeight:包括padding、border、水平滚动条,但不包括margin的元素的高度。对于inline的元素这个属性一直是0,单位px,只读元素。offsetHeight=padding+height+border+横向滚动轴高度。
(3)scrollHeight:包括当前不可见部分的元素的高度,只有出现滚动条的情况下才有意义,scrollHeight>=clientHeight。
(4)ffsetTop: 当前元素顶部距离最近父元素顶部的距离,和有没有滚动条没有关系。
(5)scrollTop: 代表在有滚动条时,滚动条向下滚动的距离也就是元素顶部被遮住部分的高度。在没有滚动条时scrollTop==0恒成立。单位px,可读可设置。
(6)clientTop:一个元素顶部边框的宽度(以像素表示)。不包括顶部外边距或内边距。clientTop 是只读的。

6.异步加载JS的方法,以及对应的适用场景?

(1)Script Dom Element
这种加载方式执行完之前会阻止onload事件的触发,所以会阻塞部分页面的初始化处理。更优的解决方法是放到onload事件里去执行。

(function(){
  var scriptEle = document.createElement("script");
  scriptEle.type = "text/javasctipt";
  scriptEle.async = true;
  scriptEle.src = "http://cdn.bootcss.com/jquery/3.0.0-beta1/jquery.min.js";
  var x = document.getElementsByTagName("head")[0];
  x.insertBefore(scriptEle, x.firstChild);
 })();
<async>属性是HTML5中新增的异步支持。此方法被称为Script DOM Element 方法。

(2) XHR Injection(XHR 注入)
通过XMLHttpRequest来获取JavaScript,然后创建一个script元素插入到DOM结构中。ajax请求成功后设置script.text为请求成功后返回的responseText。
(3)XHR Eval:XMLHttpRequest后直接把responseText放在eval()函数里面执行。
(4)Script In Irame:在父窗口插入一个iframe元素,然后再iframe中执行加载JS的操作。
(5)注释法,讲需要运行的脚本注释掉,需要执行时去掉注释并eval();
(6)defer或async
defer:属性规定当页面加载完成之后,才会执行脚本,安找一定顺序执行脚本。如果脚本需要DOM渲染,建议使用该元素。
async:乱序加载,属性规定一旦脚本可用,就会异步的加载。即当页面开始解析时,js就开始加载,同时进行。脚本执行顺序不确定。
两种方法都只适用于外部脚本且指定src属性。

<script type="text/javascript" src="demo.js" defer="defer"></script>
<script type="text/javascript" src="demo.js" async="async"></script>

7.Ajax如何解决浏览器的缓存问题?

Get请求可能导致缓存,解决方案有如下几种:

(1)在Ajax发送请求前加上anyAjaxObj.setRequestHeader(“If-Modified-Since”, “0”)。

(2)在Ajax发送请求前加上anyAjaxObj.setRequestHeader(“Cache-Control”, “no-cache”)。

(3)在URL后加上一个随机数:“fresh=” + Math.random(),常用于验证码刷新。

(4)在URL后加上时间戳:“nowtime=” + new Date().getTime();。常用于验证码刷新。

(5)Jquery使用$.ajaxSetup({cache:false})全局设置不缓存。

8.JS的节流和防抖实现和适用场景?

参考使用lodash。
防抖:

在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。

节流:

规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效。

适用场景:
防抖函数适用场景:
(1)search远程搜索框
节流函数适用场景:
(1)监听滚动条事件。

9.如何实现一个私有变量,用getName方法可以访问,不能直接访问?

function A(){
   var _private="private";
   return {
   	getName:function(){return _private;}
   }
}
var a =A();
a.getName();
10.eval的理解?

答:eval()函数解析并执行JavaScript字符串,如果参数是一个表达式,eval()函数将执行表达式,如果参数时JavaScript语句,eval()将执行JavaScript语句。开发中不建议适用eval函数。
(1)该方法只接收原始字符串作为参数,如果string参数不是原始字符串,那么该方法将不做任何改变的返回如:var a=1;eval(a)
(2)如果参数中没有合法的表达式和语句,则抛出SyntaxError异常如:eval(bbb====a)
(3)如果非法调用eval()则抛出EvalError异常,已废弃。
(4)如果传递给eval()的JavaScript代码生成了一个异常,eval()将把该异常传递给调用者如:eval(’ throw “error”;’)

猜你喜欢

转载自blog.csdn.net/qq_32013641/article/details/87652397