首页>面试题库>web前端面试题

web前端面试题及答案总会(四)

2018-11-29 08:28:00 | 查看次数 239 | 分类: 面试题库>web前端面试题 文章来源:来源:http://www.ifx666.cn

摘要内容:web前端面试题及答案总会(四)

61.你使用过JavaScript模板系统吗?

如有使用过,请谈谈你都使用过哪些库,比如Mustache.js,Handlebars等等。

62.请解释变量声明提升。

在JS里定义的变量,存在于作用域链里,而在函数执行时会先把变量的声明进行提升,仅仅是把声明进行了提升,而其值的定义还在原来位置。示例如下:

1 var test = function() {
2     console.log(name); // 输出:undefined
3     var name = "jeri";
4     console.log(name); // 输出:jeri
5 }
6 
7 test();

上述代码与下述代码等价。

1 var test = function() {
2     var name;
3     console.log(name); // 输出:undefined
4     name = "jeri";
5     console.log(name); // 输出:jeri
6 }
7 
8 test();

由以上代码可知,在函数执行时,把变量的声明提升到了函数顶部,而其值定义依然在原来位置。

63.请描述下事件冒泡机制。

冒泡型事件:事件按照从最特定的事件目标到最不特定的事件目标(document对象)的顺序触发。

捕获型事件:事件从最不精确的对象(document 对象)开始触发,然后到最精确(也可以在窗口级别捕获事件,不过必须由开发人员特别指定)。

支持W3C标准的浏览器在添加事件时用addEventListener(event,fn,useCapture)方法,基中第3个参数useCapture是一个Boolean值,用来设置事件是在事件捕获时执行,还是事件冒泡时执行。而不兼容W3C的浏览器(IE)用attachEvent()方法,此方法没有相关设置,不过IE的事件模型默认是在事件冒泡时执行的,也就是在useCapture等于false的时候执行,所以把在处理事件时把useCapture设置为false是比较安全,也实现兼容浏览器的效果。

64."attribute"和"property"的区别是什么?

1. 定义

Property:属性,所有的HTML元素都由HTMLElement类型表示,HTMLElement类型直接继承自Element并添加了一些属性,添加的这些属性分别对应于每个HTML元素都有下面的这5个标准特性: id,title,lang,dir,className。DOM节点是一个对象,因此,他可以和其他的JavaScript对象一样添加自定义的属性以及方法。property的值可以是任何的数据类型,对大小写敏感,自定义的property不会出现在html代码中,只存在js中。

Attribute:特性,区别于property,attribute只能是字符串,大小写不敏感,出现在innerHTML中,通过类数组attributes可以罗列所有的attribute。

2. 相同之处

标准的 DOM properties 与 attributes 是同步的。公认的(非自定义的)特性会被以属性的形式添加到DOM对象中。如,id,align,style等,这时候操作property或者使用操作特性的DOM方法如getAttribute()都可以操作属性。不过传递给getAttribute()的特性名与实际的特性名相同。因此对于class的特性值获取的时候要传入“class”。

3. 不同之处

1).对于有些标准的特性的操作,getAttribute与点号(.)获取的值存在差异性。如href,src,value,style,onclick等事件处理程序。
2).href:getAttribute获取的是href的实际值,而点号获取的是完整的url,存在浏览器差异。

65.为什么扩展JavaScript内置对象不是好的做法?

66.为什么扩展JavaScript内置对象是好的做法?

67.请指出document.onload和document.ready两个事件的区别。

页面加载完成有两种事件,一是ready,表示文档结构已经加载完成(不包含图片等非文字媒体文件),二是onload,指示页面包含图片等文件在内的所有元素都加载完成。

68.==和===有什么不同?

首先,== equality 等同,=== identity 恒等。 ==, 两边值类型不同的时候,要先进行类型转换,再比较。 ===,不做类型转换,类型不同的一定不等。

先说 ===,这个比较简单。下面的规则用来判断两个值是否===相等: 

  • 如果类型不同,就[不相等] 
  • 如果两个都是数值,并且是同一个值,那么[相等];(!例外)的是,如果其中至少一个是NaN,那么[不相等]。(判断一个值是否是NaN,只能用isNaN()来判断) 
  • 如果两个都是字符串,每个位置的字符都一样,那么[相等];否则[不相等]。 
  • 如果两个值都是true,或者都是false,那么[相等]。 
  • 如果两个值都引用同一个对象或函数,那么[相等];否则[不相等]。 
  • 如果两个值都是null,或者都是undefined,那么[相等]。 

再说 ==,根据以下规则: 

  • 如果两个值类型相同,进行 === 比较。 
  • 如果两个值类型不同,他们可能相等。根据下面规则进行类型转换再比较: 
  1. 如果一个是null、一个是undefined,那么[相等]。 
  2. 如果一个是字符串,一个是数值,把字符串转换成数值再进行比较。 
  3. 如果任一值是 true,把它转换成 1 再比较;如果任一值是 false,把它转换成 0 再比较。 
  4. 如果一个是对象,另一个是数值或字符串,把对象转换成基础类型的值再比较。对象转换成基础类型,利用它的toString或者valueOf方法。js核心内置类,会尝试valueOf先于toString;例外的是Date,Date利用的是toString转换。非js核心的对象,令说(比较麻烦,我也不大懂) 
  5. 任何其他组合,都[不相等]。 

69.你如何从浏览器的URL中获取查询字符串参数。

以下函数把获取一个key的参数。

 1 function parseQueryString ( name ){
 2     name = name.replace(/[\[]/,"\\\[");
 3     var regexS = "[\\?&]"+name+"=([^&#]*)";
 4     var regex = new RegExp( regexS );
 5     var results = regex.exec( window.location.href );
 6 
 7     if(results == null) {
 8         return "";
 9     } else {
10     return results[1];
11     }
12 }

70.请解释一下JavaScript的同源策略。

在客户端编程语言中,如javascript和 ActionScript,同源策略是一个很重要的安全理念,它在保证数据的安全性方面有着重要的意义。同源策略规定跨域之间的脚本是隔离的,一个域的脚本不能访问和操作另外一个域的绝大部分属性和方法。那么什么叫相同域,什么叫不同的域呢?当两个域具有相同的协议, 相同的端口,相同的host,那么我们就可以认为它们是相同的域。同源策略还应该对一些特殊情况做处理,比如限制file协议下脚本的访问权限。本地的HTML文件在浏览器中是通过file协议打开的,如果脚本能通过file协议访问到硬盘上其它任意文件,就会出现安全隐患,目前IE8还有这样的隐患。

71.请描述一下JavaScript的继承模式。

关于继承请看文章JavaScript之对象的继承

72.如何实现下列代码:[1,2,3,4,5].duplicator();//[1,2,3,4,5,1,2,3,4,5]。

73.描述一种JavaScript中实现memoization(避免重复运算)的策略。

74.什么是三元表达式?“三元”表示什么意思?

三元表达式:? :三元--三个操作对象

在表达式boolean-exp ? value0 : value1 中,如果“布尔表达式”的结果为true,就计算“value0”,而且这个计算结果也就是操作符最终产生的值。如果“布尔表达式”的结果为false,就计算“value1”,同样,它的结果也就成为了操作符最终产生的值。

75.JavaScript里函数参数arguments是数组吗? 

在函数代码中,使用特殊对象 arguments,开发者无需明确指出参数名,通过使用下标就可以访问相应的参数。

arguments虽然有一些数组的性质,但其并非真正的数组,只是一个类数组对象。其并没有数组的很多方法,不能像真正的数组那样调用.jion(),.concat(),.pop()等方法。

76.什么是"use strict";?使用它的好处和坏处分别是什么?

在代码中出现表达式-"use strict"; 意味着代码按照严格模式解析,这种模式使得Javascript在更严格的条件下运行。

好处:

  • 消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为;
  • 消除代码运行的一些不安全之处,保证代码运行的安全;
  • 提高编译器效率,增加运行速度;
  • 为未来新版本的Javascript做好铺垫。

坏处:

同样的代码,在"严格模式"中,可能会有不一样的运行结果;一些在"正常模式"下可以运行的语句,在"严格模式"下将不能运行。

77.解释"chaining"。

jQuery方法链接。直到现在,我们都是一次写一条jQuery语句(一条接着另一条)。不过,有一种名为链接(chaining)的技术,允许我们在相同的元素上运行多条jQuery命令,一条接着另一条。

提示:这样的话,浏览器就不必多次查找相同的元素。

如需链接一个动作,您只需简单地把该动作追加到之前的动作上。

78.解释"deferreds"。

开发网站的过程中,我们经常遇到某些耗时很长的javascript操作。其中,既有异步的操作(比如ajax读取服务器数据),也有同步的操作(比如遍历一个大型数组),它们都不是立即能得到结果的。

通常的做法是,为它们指定回调函数(callback)。即事先规定,一旦它们运行结束,应该调用哪些函数。

但是,在回调函数方面,jQuery的功能非常弱。为了改变这一点,jQuery开发团队就设计了deferred对象。

简单说,deferred对象就是jQuery的回调函数解决方案。在英语中,defer的意思是"延迟",所以deferred对象的含义就是"延迟"到未来某个点再执行。

79.你知道哪些针对jQuery的优化方法?

  • 1.总是从ID选择器开始继承在jQuery中最快的选择器是ID选择器,因为它直接来自于JavaScript的getElementById()方法。

例如有一段HTML代码:

 1 <div id="content">
 2     <form method="post"action="#">
 3         <h2>交通信号灯</h2>
 4         <ul id="traffic_light">
 5             <li>
 6                 <input type="radio"class="on"name="light"value="red"/>红色
 7             </li>
 8             <li>
 9                 <input type="radio"class="off"name="light"value="yellow"/>黄色
10             </li>
11             <li>
12                 <input type="radio"class="off"name="light"value="green"/>绿色
13             </li>
14         </ul>
15         <input class="button"id="traffic_button"type="submit"value="Go"/>
16     </form>
17 </div>

比如需要选择红绿单选框,那么可以使用一个tag name来限制(修饰)class,如下所示:var active_light=$(“input.on”);当然也可以结合就近的ID,如下所示:var active_light=$(“#traffic_light input.on”);  如果采用下面的选择器,那么效率是低效的。var traffic_button=$(“#content.button”);因为button已经有ID了,我们可以直接使用ID选择器。如下所示:var traffic_button=$(“#traffic_button”);当然这只是对于单一的元素来讲。如果你需要选择多个元素,这必然会涉及到DOM遍历和循环,为了提高性能,建议从最近的ID开始继承。如下所示:var traffic_lights=$(“#traffic_light input”);

  • 2.在class前使用tag(标签名)在jQuery中第二快的选择器是tag(标签)选择器(比如:$(“head”))。

跟ID选择器累时,因为它来自原生的getElementsByTagName()方法。继续看刚才那段HTML代码:

在使用tag来修饰class的时候,我们需要注意以下几点:(1)不要使用tag来修饰ID,如下所示:var content=$(“div#content”);这样一来,选择器会先遍历所有的div元素,然后匹配#content。(好像jQuery从1.3.1开始改变了选择器核心后,不存在这个问题了。暂时无法考证。)(2)不要画蛇添足的使用ID来修饰ID,如下所示:var traffic_light=$(“#content#traffic_light”);

  • 3.将jQuery对象缓存起来把jQuery对象缓存起来就是要告诉我们要养成将jQuery对象缓存进变量的习惯。

下面是一个jQuery新手写的一段代码:

1 $("#traffic_light input.on").bind("click",function(){});
2 $("#traffic_light input.on").css("border","1px dashed yellow");
3 $("#traffic_light input.on").css("background-color","orange");
4 $("#traffic_light input.on").fadeIn("slow");

但切记不要这么做。我们应该先将对象缓存进一个变量然后再操作,如下所示:

记住,永远不要让相同的选择器在你的代码里出现多次.注:(1)为了区分普通的JavaScript对象和jQuery对象,可以在变量首字母前加上$符号。(2)上面代码可以使用jQuery的链式操作加以改善。如下所示:

1 var $active_light = $("#traffic_light input.on");
2 
3 $active_light.bind("click",function(){})
4 .css("border","1px dashed yellow")
5 .css("background-color","orange")
6 .fadeIn("slow");
  • 4.如果你打算在其他函数中使用jQuery对象,那么你必须把它们缓存到全局环境中。

如下代码所示:

 1 // 在全局范围定义一个对象(例如:window对象)
 2 window.$my = {
 3     head:$("head"),
 4     trafficLight:$("#trafficLight"),
 5     trafficButton:$("#trafficButton")
 6 };
 7 
 8 function doSomething(){
 9     // 现在你可以引用存储的结果并操作它们
10     var script=document.createElement("script");
11     $my.head.append(script);
12 
13     // 当你在函数内部操作是,可以继续将查询存入全局对象中去.
14     $my.coolResults=$("#some_ul li");
15     $my.otherResults=$("#some_table td");
16 
17     // 将全局函数作为一个普通的jquery对象去使用.
18     $my.otherResults.css("border-color","red");
19     $my.trafficLight.css("border-color","green");
20 }
21 // 你也可以在其他函数中使用它.

这里的基本思想是在内存中建立你确实想要的东西,然后更新DOM。这并不是一个jQuery最佳实践,但必须进行有效的JavaScript操作。直接的DOM操作速度很慢。例如,你想动态的创建一组列表元素,千万不要这样做,如下所示:对直接的DOM操作进行限制。

1 var top_100_list = [];// 假设这里是100个独一无二的字符串
2 var $mylist = $("#mylist");// jQuery选择到<ul>元素
3 
4 for(var i = 0,l = top_100_list.length;i<l;i++) {
5     $mylist.append("<li>" + top_100_list[i] + "</li>");
6 }

我们应该将整套元素字符串在插入进dom中之前先全部创建好,如下所示:

1 $("#entryform input").bind("focus",function() {
2     $(this).addClass("ed");
3 }).bind("blur",function(){
4     $(this).removeClass("ed");
5 });
  • 5.冒泡除非在特殊情况下,否则每一个js事件(例如:click,mouseover等.)都会冒泡到父级节点。

当我们需要给多个元素调用同个函数时这点会很有用。代替这种效率很差的多元素事件监听的方法就是,你只需向它们的父节点绑定一次。比如,我们要为一个拥有很多输入框的表单绑定这样的行为:当输入框被选中时为它添加一个class传统的做法是,直接选中input,然后绑定focus等,如下所示:

1 $("#entryform").bind("focus",function(e) {
2     var $cell = $(e.target); // e.target捕捉到触发的目标元素
3     $cell.addClass("ed");
4 }).bind("blur",function(e) {
5     var $cell = $(e.target);
6     $cell.removeClass("ed");
7 });

当然上面代码能帮我们完成相应的任务,但如果你要寻求更高效的方法,请使用如下代码:

通过在父级监听获取焦点和失去焦点的事件,对目标元素进行操作。在上面代码中,父级元素扮演了一个调度员的角色,它可以基于目标元素绑定事件。如果你发现你给很多元素绑定了同一个事件监听,那么现在的你肯定知道哪里做错了。

  • 6.推迟到$(window).load。

jQuery对于开发者来说有一个很诱人的东西,可以把任何东西挂到$(document).ready下。尽管$(document).rady确实很有用,它可以在页面渲染时,其它元素还没下载完成就执行。如果你发现你的页面一直是载入中的状态,很有可能就是$(document).ready函数引起的。你可以通过将jQuery函数绑定到$(window).load事件的方法来减少页面载入时的cpu使用率。它会在所有的html(包括iframe)被下载完成后执行。一些特效的功能,例如拖放,视觉特效和动画,预载入隐藏图像等等,都是适合这种技术的场合。

  • 7.压缩JavaScript。

在线压缩地址:http://dean.edwards.name/packer/压缩之前,请保证你的代码的规范性,否则可能失败,导致Js错误。

  • 8.尽量使用ID代替Class。

 前面性能优化已经说过,ID选择器的速度是最快的。所以在HTML代码中,能使用ID的尽量使用ID来代替class。看下面的一个例子:

 1 // 创建一个list
 2 var $myList = $('#myList');
 3 var myListItems = '<ul>';
 4 
 5 for(var i = 0; i < 1000; i ++) {
 6     myListItems += '<li class = "listItem'+i+'">This is a list item</li>';
 7     // 这里使用的是class
 8 }
 9 
10 myListItems += '</ul>';
11 $myList.html(myListItems);
12 // 选择每一个li
13 
14 for(var i = 0; i<1000; i++) {
15     var edItem = $('.listItem' + i);
16 }

在上段代码中,选择每个li总共只用了61毫秒,相比class的方式,将近快了100倍。       在代码最后,选择每个li的过程中,总共用了5066毫秒,超过5秒了。接着我们做一个对比,用ID代替class:

  • 9.给选择器一个上下文。

jQuery选择器中有一个这样的选择器,它能指定上下文。jQuery(expression,context);通过它,能缩小选择器在DOM中搜索的范围,达到节省时间,提高效率。普通方式:$(‘.myDiv’)改进方式:$(‘.myDiv’,$(“#listItem”))。

  • 10.慎用.live()方法(应该说尽量不要使用)。

这是jQuery1.3.1版本之后增加的方法,这个方法的功能就是为新增的DOM元素动态绑定事件。但对于效率来说,这个方法比较占用资源。所以请尽量不要使用它。例如有这么一段代码:

 1 <script type="text/javascript">
 2     $(function(){
 3 
 4         $("p").click(function(){
 5             alert($(this).text());
 6         });
 7 
 8         $("button").click(function(){
 9             $("<p>this is second p</p>").appendTo("body");
10         });
11     })
12 </script>
13 <body>
14     <p>this is first p</p>
15     <button>add</button>
16 </body>

运行后,你会发现新增的p元素,并没用被绑定click事件。你可以改成.live(“click”)方式解决此问题,代码如下:

 1 $(function() {
 2     $("p").live("click",function() {
 3         // 改成live方式
 4         alert($(this).text());
 5     });
 6 
 7     $("button").click(function() {
 8         $("<p>this is second p</p>").appendTo("body");
 9     });
10 })

但我并不建议大家这么做,我想用另一种方式去解决这个问题,代码如下:

 1 $(function() {
 2     $("p").click(function() {
 3         alert($(this).text());
 4     });
 5 
 6     $("button").click(function() {
 7         $("<p>this is second p</p>").click(function() {
 8             // 为新增的元素重新绑定一次
 9             alert($(this).text());
10         }).appendTo("body");
11     });
12 })

虽然我把绑定事件重新写了一次,代码多了点,但这种方式的效率明显高于live()方式,特别是在频繁的DOM操作中,这点非常明显。

80.请解释.end()的用途。

在官方的API上是这样描述end()方法的:“回到最近的一个"破坏性"操作之前。即,将匹配的元素列表变为前一次的状态。”;看样子好像是找到最后一次操作的元素的上一元素,在如下的例子中:html代码:

复制代码代码如下:

1 <div>测试内容1</div><div>测试内容2</div>

jQuery代码:

复制代码代码如下:

1 $('<p>新增内容</p>').appendTo('div').addClass('c1').end().addClass('c2');

复制代码代码如下:

1 <div>测试内容1
2     <p class="c1 c2">新增内容</p>
3 </div>
4 <div>测试内容2
5     <p class="c1">新增内容</p>
6 </div>

这里我就有一点不太明白了,怎么只有第一个<p>标签有两个样式,end()方法后返回的是什么,在火狐里添加了监控,得到如下结果:1.$('<p>新增内容</p>').appendTo('div')返回的是:[p,p]对象数组,即新增后的两个p标签;2.$('<p>新增内容</p>').appendTo('div').addClass('c1')返回的是:[p.c1,p.c1]对象数组,即添加了c1类样式后的p对象数组;3.$('<p>新增内容</p>').appendTo('div').addClass('c1').end()返回的是[p.c1],是第1个<div>中的<p>,在2操作中,最后“破坏”的是第2个<div>中的<p>,所以他的前一次操作的对象是第1个<div>中的<p>,返回的就是它;4.$('<p>新增内容</p>').appendTo('div').addClass('c1').end().addClass('c2')返回的仍然是第1个<div>中的<p>;现在算是有点明白了,关键是要搞清楚最后一次操作的元素的上一元素是什么。

上一篇: web前端面试题及答案总会(二)

下一篇: web前端面试题 本文是在GitHub上看到一个大牛总结的前端常见面试题

验证码:
评论列表
  • 文章推荐

    09-19 | 查看次数 786

    《深入理解Spring Cloud与微服务构建》PDF下载

    09-14 | 查看次数 197

    bootstrap tooltip 提示框的样式、提示字体颜...

    09-01 | 查看次数 200

    json字符串与java对象互转,json字符串转化为map...

    08-04 | 查看次数 383

    java面试题及答案---2018核心Java面试问题与解答...

    08-03 | 查看次数 900

    java面试题及答案---2018核心Java面试问题与解答...

    最新评论
    文章标题:管理和发布文章java cms

    评论内容:能下载吗

    评论时间:2018-12-12 01:30:02

  • 返回顶部
    欢迎投稿
    返回底部