几道前端面试题

mac2022-06-30  74

简答题: 1.事件绑定的几种方式?几种方式的区别以及优缺点?(原生js)    (1)、html元素里直接写,例如:<div οnclick="javascript:alert("click")" ></div>   不推荐这么绑定。   (2)、W3C 推荐的js绑定。如:     document.getElementById('test').addEventListener('click',function(){       alert('click')     })   该方法同时支持事件处理的捕获和冒泡阶段。事件阶段取决于addEventListener最后的参数设置:false (冒泡) 或 true (捕获)。 在事件处理函数内部,this关键字引用当前元素。 事件对象总是可以通过处理函数的第一个参数(e)捕获。 可以为同一个元素绑定你所希望的多个事件,同时并不会覆盖先前绑定的事件,但是IE不支持,需要用attachEvent代替。 (3)传统的on绑定。   document.getElementById('test').onClick= function(){     alert('click')   }   传统方法只会在事件冒泡中运行,而非捕获和冒泡   一个元素一次只能绑定一个事件处理函数。新绑定的事件处理函数会覆盖旧的事件处理函数 事件对象参数(e)仅非IE浏览器可用 2.什么是事件委托?    事件委托就是事件目标自身不处理事件,而是把处理任务委托给其父元素或者祖先元素,甚至根元素(document)。 事件委托是利用事件的冒泡原理来实现的,何为事件冒泡呢?就是事件从最深的节点开始,然后逐步向上传播事件,举个例子:页面上有这么一个节点树,div>ul>li>a;比如给最里面的a加一个click点击事件,那么这个事件就会一层一层的往外执行,执行顺序a>li>ul>div,有这样一个机制,那么我们给最外面的div加点击事件,那么里面的ul,li,a做点击事件的时候,都会冒泡到最外层的div上,所以都会触发,这就是事件委托,委托它们父级代为执行事件。 3.css动画如何做性能优化?    这一题,本人也不太会,哈哈。一搜索出现一堆都是抄袭的同一篇文章,还请有经验人士说一下大家共同学习。 4.什么是模块化开发?你用的哪种方式进行模块化开发    一个模块就是实现特定功能的文件,有了模块,我们就可以更方便地使用别人的代码,想要什么功能,就加载什么模块。 AMD 模块将被异步加载,模块加载不影响后面语句的运行。所有依赖某些模块的语句均放置在回调函数中。requirejs遵循此规范。 CMD 在CMD中,一个模块就是一个文件,格式为: 区别:    1. 对于依赖的模块,AMD 是提前执行,CMD 是延迟执行。不过 RequireJS 从 2.0 开始,也改成可以延迟执行(根据写法不同,处理方式不同)。CMD 推崇 as lazy as possible.        2. CMD 推崇依赖就近,AMD 推崇依赖前置。 5.什么是闭包?闭包的应用场景   见第6题的链接里,王福朋对这部分也有很好的讲解。 6.Function.prototype是什么?Object.prototype是什么?   对于这个问题:给大家一个非常好的链接,看了之后绝对对这类问题理解的很透彻   http://www.cnblogs.com/wangfupeng1988/tag/原型链/ 7.你知道哪几种跨域请求数据的方式?jsonp的原理是什么?    就是利用<script>标签没有跨域限制的“漏洞”(历史遗迹啊)来达到与第三方通讯的目的。当需要通讯时,本站脚本创建一个<script>元素,地址指向第三方的API网址,形如: <script src="http://www.example.net/api?param1=1¶m2=2"></script> 并提供一个回调函数来接收数据(函数名可约定,或通过地址参数传递)。 第三方产生的响应为json数据的包装(故称之为jsonp,即json padding),形如: callback({"name":"hax","gender":"Male"})   8.回调嵌套太多,你是怎么解决的?   这个问题就是nodejs里面会很容易出现的回调地狱的解决问题。问题的原因在于异步执行时,根据回调函数的结果进行下一步操作,这一步操作里又会有一个回调,说的有点乱,看栗子:    $.ajax(  { url: url,   method: 'get',   success: function(res) {       $.ajax({         url: url,         method: 'get',         data:res //这里利用了第一次请求的结果再次请求         success: function(res2) {               resolve(res2);         },         error: function(xhr, statusText) {             reject(statusText);           }      });     },    error: function(xhr, statusText) {   reject(statusText);    } });

 

这才只有两个嵌套,更多层的话你会疯掉的!解决这个问题的先要去了解一下Promise ,目前处理此类问题的js库有:Bluebird,Async.js 等等吧   9.如何实现对象方法的链式调用?    主要是生成对象,对象的每个方法里执行完想用的操作后return this(对象本身);举个栗子:   一个只有一个name属性的类,提供修改name和重置name的方法, //链式调用 function ChainTest(name){ this.name = name; this.originalName = name; } ChainTest.prototype.changeName = function(newName){ this.name = newName; return this; } ChainTest.prototype.reset = function(){ this.name = this.originalName; return this; } var chain = new ChainTest("zhangsan");//新建对象 console.log(chain.name )// zhangsan chain.changeName('lisi'); console.log(chain.name ) // lisi chain.changeName('wangwu').reset();//链式调用 console.log(chain.name ) // zhangsan 10.Number函数与parseInt函数有哪些区别? 答: Number():可以用于任何数据类型转换成数值; parseInt()、parseFloat():专门用于把字符串转换成数值; 转换规则具体可以参考:http://www.cnblogs.com/hyuq/p/4131200.html   编程题: 1.请将字符串“asjchbnwnkanhe”按照字典顺序排序    解题思路:1、将字符串分解成数组。2、将数组排序。3、合并成数组。 function sort(str){   var arr = str.split("");   arr = arr.sort();   var resStr = arr.join("");   return resStr ; } 2.NaN属于什么类型?请写一个判断函数,功能如下:只有输入NaN的时候为true,其余输入值全部为false 解题思路:typeof(NaN)看出NaN是一个number类型的数据。NaN和任何数包括NaN自身相比较都是false,所以不能直接根据if(NaN == NaN)进行判断,先判断是否为number类型,然后再看他是不是0,如果不是则为NaN function myIsNaN(num){   if(typeof(num) == "number"){     if(!num && num != 0){       return true   }else{     return false   }   }else{     return false   } } 3.请写出程序输出结果: var arr = []; (function run(){   var i=0;   for(;i<5;i++){     arr.push(function(){   console.log(i);     return i;   });   } })(); arr = [] arr[2]();//请写出输出 var arr1 = arr.map(function(i){return i()}); var result = arr1.reduce(function(a,b){return a+b;}); console.log(result);//请写出输出   解题思路:首先run是一个自执行的函数,函数的功能是向arr[0] ~ arr[4] 中个放置一个函数,每个函数都是 function(){   console.log(i);   return i; } 这个i引用的是run函数里的i,所以存在了一个闭包的现象(实际上数组里的每个元素都是这个函数,由于这个函数没有被执行,所以每个数组里的i是不确定的,只有到执行的时候i是什么值,输出才是什么值),所以 arr[2] = function(){   console.log(i);   return i; } 执行的时候i是run函数里的i这时的i已经是5了,所以: arr[2]() 输出为5; var arr1 = arr.map(function(i){   return i() }); 这一步首先arr.map的返回值是一个数组,根据之前的分析可得: arr1 = [5,5,5,5,5]; 接下来就是这个: var result = arr1.reduce(function(a,b){return a+b;});   首先是这个数组reduce函数(貌似不太常见这个方法),这个方法的的理解: reduce(callback, initialValue)会传入两个变量。回调函数(callback)和初始值(initialValue)。假设函数它有个传入参数,prev和next,index和array。prev和next你是必须要了解的。reduce(callback, initialValue)会传入两个变量。回调函数(callback)和初始值(initialValue)。假设函数它有个传入参数,prev和next,index和array。prev和next你是必须要了解的。如果不太理解的话请移步: http://www.jb51.net/article/60502.htm 先学一下,基本上就是遍历一下数组,但是每次遍历的是数组紧挨着的两个元素。 理解了这个函数之后应该很容易得出结果: result = 25; 4.一个楼梯一共n个台阶,每次可以走1个台阶或者走2个台阶,请编写代码,输入为n,输出为多少种不同的走法? 解题思路:这是一个算法题。(作为找前端的人来说,这道题实在浪费时间,而且不应该,重要的是发现规律,发现不了肯定解决不了了) 先运用一下高中的数学解题思维看一下规律: N Ways 1 1 //n=1 时只能走一步,所以只有一种方法 2 2 //n =2 时,一次走一步和一次走两步两种方法 3 3 //一次走一步,先走一步再走两步,先走两步再走一步 4 5 //自己琢磨吧,这里写不下了 5 8 //规律可以看出来了f[n] = f[n-1] + f[n-2] //这里肯定会有递归算法了 function getWays(n){ if(n == 1){ return 1 }else if(n == 2){ return 2 }else{ //递归调用 return getWays(n-1) = getWays(n-2) } } 6.结果输出什么?为什么? var a={}, b={key:'b'}, c={key:'c'};   a[b]=123; a[c]=456;   console.log(a[b]); 解题思路: 首先这题得知道,object的属性值是不是可以为object?当然是不可以的。 因为键名称只能是字符串,b/c单作建会调用toString得到的都是[object Object],a[b],a[c]都等价于a["[object Object]"],那不就是更新[object Object]这个键的值了,执行后查看下a对象的的属性值就会发现确实是这样。

 

转载于:https://www.cnblogs.com/mdengcc/p/6510323.html

最新回复(0)