让我印象深刻的javascript面试题

zdgg3871 7年前
   <h2>1.前言</h2>    <p>对于一个web前端来说,面试的时候,难免会遇到javascript的面试题。就我自己而言。有几道面试题,有些是我面试遇到的,有些是在网上看到的,但是都印象深刻。今天就来简单分析一下我遇到的,印象深刻的一些面试题!主要目的希望能让小伙伴学到一些东西,如过以后遇到类似的情况,就记得不要掉坑了!</p>    <h2>2.预解析</h2>    <p>预解析:在当前作用域下,js运行之前,会把带有var和function关键字的事先声明,但不会赋值(个人见解)</p>    <p>对预解析印象深刻,并不是因为难,而是要细心,稍微一粗心,答案就写错了!我遇到预解析的题目不止一道,有两道我现在还能记住,我说下!</p>    <h3>2-1.预解析1</h3>    <pre>  <code class="language-javascript">alert(a)  a();  var a=3;  function a(){      alert(10)  }     alert(a)  a=6;  a();      ------------分割线------------------    alert(a)  a();  var a=3;  var a=function(){      alert(10)  }     alert(a)  a=6;  a();</code></pre>    <p>看到这个代码,当时答错了。后来请教了朋友,然后自己再理解下,就理顺了!</p>    <p>考点其实就两个,第一变量声明提前,第二函数声明优先于变量声明!</p>    <p>下面我简单分析一下,</p>    <p>第一部分运行结果:</p>    <p>1.函数声明优先于变量声明,所以,刚开始,a就是 function a(){alert(10)} ,就会看到这个函数。</p>    <p>2. a() ,执行函数,就是出现 alert(10)<br> 3.执行了 var a=3; 所以 alert(a) 就是显示 3</p>    <p>4.由于 a 不是一个函数了,所以往下在执行到 a() 的时候, 报错。</p>    <p>第二部分运行结果:</p>    <p>1.underfind</p>    <p>2.报错</p>    <p>在之前说过,预解析是把带有 var 和 function 关键字的事先声明,但不会赋值。所以一开始是 underfind ,然后报错是因为执行到 a() 的时候, a 并不是一个函数。</p>    <pre>  <code class="language-javascript">//函数表达式,和变量声明同等  var a=function(){      alert(10)  }   //函数声明,优于变量声明      function a(){      alert(10)  }</code></pre>    <h3>2-2.预解析和作用域</h3>    <pre>  <code class="language-javascript">var a=0;  function aa(){      alert(a)      a=3  }  //结果是什么都没发生,因为要执行aa函数才会执行alert(0)    ------------分割线1------------------    var a=0;  function aa(){      alert(a)      var a=3  }  aa();  //underfind  在aa函数里面,有var a=3,那么在aa作用域里面,就是把a这个变量声明提前,但是不会赋值,所以是underfind    ------------分割线2------------------    var a=0;  function aa(a){      alert(a)      var a=3  }  aa(5)  alert(a)  //5,0   在函数体内,参数a的优先级高于变量a    ------------分割线3------------------    var a=0;  function aa(a){      alert(a)      a=3  }  aa(5)  alert(a)  //5,0   在函数体内,执行alert(a)和a=3,修改的的并不是全局变量a,而是参数a    ------------分割线4------------------    var a=0;  function aa(a){      alert(a)      var a=3      alert(a)  }  aa(5)  //5,3  //这个我也有点不理解,请教网上的说法,有两个答案(小伙伴如果知道怎么理解,欢迎在评论上指点)  //1.参数优先级高于变量声明,所以 变量n的声明其实被忽略了,此时相当于  //var a=0;  //function aa(a){  //  var a=5;  //    alert(a)  //    a=3  //    alert(a)  //}  //aa(5)    //2.形参和局部变量优先级一样,此时相当于  //var a=0;  //function aa(a){  //  var a;    先声明  //  a=5      由于形参和变量名称一样,覆盖了!  //    alert(a)  //    a=3  //    alert(a)  //}  //aa(5)    ------------分割线5------------------    var a=0;  function aa(a){      alert(a)      a=3      alert(a)  }  aa()  alert(a)  //underfind  3  0   //首先,参数优先级高于全局变量,由于没传参数,所以是underfind  //a=3,实际上修改的时形参a的值,并不是全局变量a,往下alert(a)也是形参a  //最后的alert(a),你懂的</code></pre>    <h2>3.递归</h2>    <h3>3-1.费波纳茨数组</h3>    <p>这个不多说了,很简单,但是很经典。就是当前项等于前两项的和</p>    <pre>  <code class="language-javascript">var arr=[];  for(var i=0;i<10;i++ ){      i<=1?arr.push(1):arr.push(arr[i-1]+arr[i-2]);  }  console.log(arr)</code></pre>    <h3>3-2.数据排列</h3>    <p>比如 123454321 23456765432</p>    <p>这个怎么做呢?当时我的做法的分两步写,先展示前面,再展示后面</p>    <p>代码是</p>    <pre>  <code class="language-javascript">//01234543210  //先展示前面的   01234  //n:开始的数字    m:结束的数字  function num1(n,m){      for(var i=n;i<m;i++){          //再展示后面的 543210          console.log(i);          if(i===m-1){              num2(n,m)          }      }  }  function num2(n,m){      for(var i=m;i>=n;i--){          console.log(i)      }  }  test(2,5)  //2345432</code></pre>    <p>这样代码太多了,后来研究了这种</p>    <pre>  <code class="language-javascript">function num(n,m){      console.log(n);      if(n<m){          test(n+1,m);          console.log(n);      }  }  num(2,5)  //2345432</code></pre>    <p>解释如下</p>    <pre>  <code class="language-javascript">1.首先执行num(2,5),就是  console.log(2); ->  test(3,5);  ->  console.log(2);        //执行test(3,5);  就是是相当于   console.log(3); -> test(4,5); -> console.log(3); 下面以此类推  console.log(2); -> console.log(3); -> test(4,5); -> console.log(3); ->  console.log(2);      然后就是    console.log(2); -> console.log(3); -> console.log(4); -> test(5,5); -> console.log(4); -> console.log(3); ->  console.log(2);    最后就是    console.log(2); -> console.log(3); -> console.log(4); -> console.log(5); -> console.log(4); -> console.log(3); ->  console.log(2);</code></pre>    <h2>4.其它</h2>    <h3>4-1</h3>    <pre>  <code class="language-javascript">function foo1()  {   return {       bar: "hello"   };  }     function foo2()  {   return   {       bar: "hello"   };  }  var a=foo1();  var b=foo2();  console.log(a) //Object {bar: "hello"}  console.log(b) //underfind  //仔细看就知道了</code></pre>    <h3>4-2</h3>    <p>网上看到的题目,我自己改造下 <a href="/misc/goto?guid=4959750404779801353" rel="nofollow,noindex">80%应聘者都不及格的JS面试题</a></p>    <pre>  <code class="language-javascript">for (var i = 0; i < 5; i++) {    console.log(i);  }  console.log(i);  //这个大家应该很快就知道了,012345        for (var i = 0; i < 5; i++) {   setTimeout(function() {    console.log(i);   }, 1000);  }  console.log(i);  //这个大家就要小心一点了,答案是5    55555  //在setTimeout执行之前,for循环早就执行完了,i的值早已经是5了,所以一开始是执行,最后面的console.log(i);  //在for循环的时候一下子自定义5个setTimeout,大概一秒后,就是输出55555        for (var i = 0; i < 5; i++) {   (function(j) { // j = i    setTimeout(function() {     console.log(j);    }, 1000);   })(i);  }  console.log(i);   //这里的解析和上面基本一样,只是用闭包来记录每一次循环的i,  //所以答案是5     01234        var output = function (i) {   setTimeout(function() {    console.log(i);   }, 1000);  };     for (var i = 0; i < 5; i++) {   output(i); // 这里传过去的 i 值被复制了  }  console.log(i);    //这里的解析和上面基本一样,把i当参数传进output,记录每一次循环的i,  //所以答案是5     01234        for (let i = 0; i < 5; i++) {   setTimeout(function() {    console.log(i);   }, 1000);  }  console.log(i);  //结果是  报错   01234   //注意i是用let定义的,不是var</code></pre>    <h2>5.小结</h2>    <p>首先,要说一个就是这些是我自己遇到的题目里面,印象比较深刻的一些题目,并不一定是常见的题目。</p>    <p>然后,这篇文章可以说是我的一个笔记,记录着我遇到过的题目。我发这样的面试题文章给小伙伴看,目的不是为了让小伙伴们记住题目和答案,或者是应付面试,这样没有意义,也不现实!我的目的是为了让大家可以学习一下,通过题目来知道一些原理和运行的机制,或者是知道一些可能的‘陷阱’。</p>    <p>另外,我遇到过的实际的操作题也很多,比如 数组去重,打乱数组,统计数组各个元素出现的次数, 字符串各个字符的出现次数,获取地址链接的各个参数 等等。这些题目不仅在面试题出现的比较多,在实际项目开发也会经常用到,小伙伴可以自己学习。当然我自己也有封装过一些函数,就是实现上面说的那些操作的函数,这个我近期也会写文章,记录我封装过哪些函数,封装过哪些常用的功能,到时候再分享。有什么需要改正的,或者好的建议,也欢迎指出!</p>    <p> </p>    <p>来自:https://segmentfault.com/a/1190000010114505</p>    <p> </p>