几个面试题

几个前端基础面试题
  • 关于作用域和自由变量的场景题

    let i;
    for (i = 1; i <= 3; i++ ) {
      setTimeout(function(i) {
        console.log(i);
      },0);
    }
    以上代码输出什么?
    

    如何修改,让上面代码输出1,2,3

    方案一:

    for(let i = 1; i <= 3; i++) {
      setTimeout(function(){
        console.log(i);
      },0)
    }
    

    方案二:

    // 使用立即执行函数
    let i;
    for (i = 1; i <= 3; i++) {
        (function(j) {
            setTimeout(function() {
                console.log(j);
            }, 0);
        })(i);
    }
    

    方案三

    // 借用setTimeout()的参数传入
    let i;
    for (i = 1; i <= 3; i++) {
        setTimeout(function(j) {
            console.log(j);
        }, 0, i)
    }
    
  • 判断字符串以字母开头,后面字母数字下划线,长度6-30 (知识点:正则)

    const reg = /^[a-zA-Z]w{5-29}$/
    
  • 手写trim,保证浏览器的兼容

    // 干掉开头和结尾的空格
    Strig.prototy.trim = function () {
      	return this.replace(/^s+/,"").replace(/^s+$/,'');
    }
    //知识点 原型 this 正则表达式
    
  • 如何获取多个数字中的最大值

    function max() {
      const nums = Array.prototype.slice.call(arguments);
      let max = 0;
      nums.forEach(item=>{
        if (n > max) max = n;
      });
      return max;
    }
    

    用Math.max()

    function max() {
      return Math.max(Array.prototype.slice.call(arguments));
    }
    
  • JS的继承?

    // extends class 继承
    // prototype 继承
    
  • 如何捕获异常

    • 手动捕获:
    try {
      
    } catch(ex) {
      
    } finally {
      
    }
    
    • 自动捕获
    window.onerror = function (message , source , lineNum, colNum, error ) {
      // 第一, 对于跨域的js ,如cdn不会有详细的报错信息
      // 第二, 对于压缩的js , 要配合sourceMap 反查未压缩的代码行和列
    }
    
  • JSON

    • 是一种数据格式,本质是一种字符串
    • json格式和JS对象结构一致,对JS语言相当的友好
    • window.JSON是一个全局对象,JSON.parse() , JSON.stringigy()
  • 获取当前页面的url参数

    //正则匹配来获取
    function query(name ) {
      //去除?
      const search = location.href.substr(1);
      const reg = new RegExp(`(^|&)${name}=([^&]*)(&|$)`,'i');
      const res = search.match(reg);
      if (!res) {
        return null;
      }
      return res[2];
    }
    
    //使用URLSearchParams
    function query(name) {
        const search = location.search;
        return new URLSearchParams(search).get(name);
    }
    
    // 使用split对字符串进行拆分
    function query(name) {
      const search = location.serach.substr(1);
      search.split("&").forEach(item=>{
        const arr = item.split('=');
        if (arr[0] === name) {
          return arr[1];
        }
      });
      return null;
    }
    
  • 数组去重的方式

    使用Set---无序结构,不可重复

    let unique = (arr)=>[...new Set(arr)];
    

    遍历

    function unique(arr) {
      const res = [];
      arr.forEach(item => {
        // indexOf 也是遍历
        if (res.indexOf(item) < 0) {
          res.push(item);
        }
      });
      return res;
    }
    // O(n^2)
    
  • 手写falt,考虑多层级, 就是拍平数组

    function flat(arr) {
      const isDeep = arr.some(item=>item instanceof Array);
      if (!isDeep) return arr;
      // 递归
      const res = Array.prototype.concat.apply([],arr);
      return flat(res);
    }
    
  • 将url参数解析为JS对象

    function queryToObj() {
      const res = {};
      const search = location.serach.substr(1);
      search.split("&").forEach(item=>{
        const arr = item.split('=');
        res[arr[0]] = arr[1];
      });
      return res;
    }
    
  • 手写深拷贝

    function deepClone(obj) {
      if (typeof obj !== 'object' || obj == null) {
        return obj;
      }
      let cloneObj = Array.isArray(obj)?[]:{};
      for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
          if (obj[key] && typeof obj[key] === 'object') {
            cloneObj[key] = deepClone(obj[key]);
          } else {
            cloneObj[key] = obj[key];
          }
        }
      }
      return cloneObj;
    }
    
    function  deepClone(obj) {
      const cloneObjStr = JSON.stringify(obj);
      return JSON.parse(cloneObjStr);
    }
    

    Object.assign不是深拷贝,只是拷贝第一层级的拷贝

  • RAF requesAnimationFrame

    动画 60帧每秒 16.67ms更新

    RAF 浏览器会自动控制 setTimeout手动控制

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
            #div1 {
                 100px;
                height: 50px;
                background-color: red;
            }
        </style>
    </head>
    
    <body>
        <p>JS真题演示</p>
        <div id="div1"></div>
        <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js"></script>
        <script src="./RAF.js"></script>
    </body>
    
    </html>
    
    // 浏览器能够自动控制
    const $div1 = $('#div1');
    const currentWidth = 100;
    const maxWidth = 640;
    function animate() {
      currentWidth = currentWidth + 3;
      $div1.css('width',currentWidth);
      if (currentWidth < maxWidth) {
        window.requestAnimationFrame(animate);
      }
    }
    animate();
    
    // 硬核动画, 自己动手写
    function animate() {
      currentWith += 3;
      $div1.css('width',currentWidth);
      if (currentWidth < maxWidth) {
        setTimeout(animate,16.3);
      }
    }
    animate();
    
  • 前端性能优化

慢慢来,比较快!基础要牢,根基要稳!向大佬致敬!
原文地址:https://www.cnblogs.com/rookie123/p/14235735.html