• 社招前端一面经典手写面试题集锦


    对象数组列表转成树形结构(处理菜单)

    [
        {
       
            id: 1,
            text: '节点1',
            parentId: 0 //这里用0表示为顶级节点
        },
        {
       
            id: 2,
            text: '节点1_1',
            parentId: 1 //通过这个字段来确定子父级
        }
        ...
    ]
    
    转成
    [
        {
       
            id: 1,
            text: '节点1',
            parentId: 0,
            children: [
                {
       
                    id:2,
                    text: '节点1_1',
                    parentId:1
                }
            ]
        }
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    实现代码如下:

    function listToTree(data) {
       
      let temp = {
       };
      let treeData = [];
      for (let i = 0; i < data.length; i++) {
       
        temp[data[i].id] = data[i];
      }
      for (let i in temp) {
       
        if (+temp[i].parentId != 0) {
       
          if (!temp[temp[i].parentId].children) {
       
            temp[temp[i].parentId].children = [];
          }
          temp[temp[i].parentId].children.push(temp[i]);
        } else {
       
          treeData.push(temp[i]);
        }
      }
      return treeData;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    前端手写面试题详细解答

    实现一个padStart()或padEnd()的polyfil

    String.prototype.padStartString.prototype.padEndES8中新增的方法,允许将空字符串或其他字符串添加到原始字符串的开头或结尾。我们先看下使用语法:

    String.padStart(targetLength,[padString])
    
    • 1

    用法:

    'x'.padStart(4, 'ab') // 'abax'
    'x'.padEnd(5, 'ab') // 'xabab'
    
    // 1. 若是输入的目标长度小于字符串原本的长度则返回字符串本身
    'xxx'.padStart(2, 's') // 'xxx'
    
    // 2. 第二个参数的默认值为 " ",长度是为1的
    // 3. 而此参数可能是个不确定长度的字符串,若是要填充的内容达到了目标长度,则将不要的部分截取
    'xxx'.padStart(5, 'sss') // ssxxx
    
    // 4. 可用来处理日期、金额格式化问题
    '12'.padStart(10, 'YYYY-MM-DD') // "YYYY-MM-12"
    '09-12'.padStart(10, 'YYYY-MM-DD') // "YYYY-09-12"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    polyfill实现:

    String.prototype.myPadStart = function (targetLen, padString = " ") {
       
      if (!targetLen) {
       
        throw new Error('请输入需要填充到的长度');
      }
      let originStr = String(this); // 获取到调用的字符串, 因为this原本是String{},所以需要用String转为字符串
      let originLen = originStr.length; // 调用的字符串原本的长度
      if (originLen >= targetLen) return originStr; // 若是 原本 > 目标 则返回原本字符串
      let diffNum = targetLen - originLen; // 10 - 6 // 差值
      for (let i = 0; i < diffNum; i++) {
        // 要添加几个成员
        for (let j = 0; j < padString.length; j++) {
        // 输入的padString的长度可能不为1
          if (originStr.length === targetLen) break; // 判断每一次添加之后是否到了目标长度
          originStr = `${
         padString[j]}${
         originStr}`;
        }
        if (originStr.length === targetLen) break;
      }
      return originStr;
    }
    console.log('xxx'.myPadStart(16))
    console.log('xxx'.padStart(16))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    还是比较简单的,而padEnd的实现和它一样,只需要把第二层for循环里的${padString[j]}${orignStr}换下位置就可以了。

    实现字符串翻转

    在字符串的原型链上添加一个方法,实现字符串翻转:

    String.prototype._reverse = function(a){
       
        return a.split("").reverse().join("");
    }
    var obj = new String();
    var res = obj._reverse ('hello');
    console.log(res);    // olleh
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    需要注意的是,必须通过实例化对象之后再去调用定义的方法,不然找不到该方法。

    实现instanceOf

    // 模拟 instanceof
    function instance_of(L, R) {
      //L 表示左表达式,R 表示右表达式
      var O = R.prototype; // 取 R 的显示原型
      L = L.__proto__; // 取 L 的隐式原型
      while (true) {
        if (L === null) return false;
        if (O === L)
          // 这里重点:当 O 严格等于 L 时,返回 true
          return true;
        L = L.__proto__;
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    实现观察者模式

    观察者模式(基于发布订阅模式) 有观察者,也有被观察者

    观察者需要放到被观察者中,被观察者的状态变化需要通知观察者 我变化了 内部也是基于发布订阅模式,收集观察者,状态变化后要主动通知观察者

    class Subject {
        // 被观察者 学生
      constructor(name) {
       
        this.state = 'happy'
        this.observers = []; // 存储所有的观察者
      }
      // 收集所有的观察者
      attach(o){
        // Subject. prototype. attch
        this.observers.push(o)
      }
      // 更新被观察者 状态的方法
      setState(newState) {
       
        this.state = newState; // 更新状态
        // this 指被观察者 学生
        this.observers.forEach(o => o.update(this)) // 通知观察者 更新它们的状态
      }
    }
    
    class Observer{
        // 观察者 父母和老师
      constructor(name) {
       
        this.name = name
      }
      update(student) {
       
        console.log('当前' + this.name + '被通知了', '当前学生的状态是' + student.state)
      }
    }
    
    let student = new Subject('学生'); 
    
    let parent = new Observer('父母'); 
    let teacher = new Observer('老师'); 
    
    // 被观察者存储观察者的前提,需要先接纳观察者
    student. attach(parent); 
    student. attach(teacher); 
    student. setState('被欺负了');
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    实现some方法

    Array.prototype.mySome=function(callback, context = window){
       
                 var len = this.length,
                     flag=false,
               i = 0;
    
                 for(;i < len; i++){
       
                    if(callback.apply(context, [this[i], i , this])){
       
                        flag=true;
                        break;
                    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
  • 相关阅读:
    (续)SSM整合之springmvc笔记(RESTful之RESTful案例)(P148-153)
    写给自己:入职两个月的收获与变化
    idea项目设置鼠标右键点击文件夹通过IDEA打开
    股指期货的详细玩法功能与应用解析
    Cys(Npys)-(Arg)₉,H2N-C(Npys)-RRRRRRRRR-OH
    蓝牙beacon
    【API篇】十一、Flink水位线传递与迟到数据处理
    表白墙完善(数据库,前端,后端Servlet),再谈Cookie和Session。以及一个关于Cookie的练习小程序
    传奇开服教程:传奇开服在哪些网站打广告?传奇发布站打广告技巧
    用JAVA如何实现word文档在线预览
  • 原文地址:https://blog.csdn.net/helloworld1024fd/article/details/126900767