前端中级工程师 - 手写编程题

题目一

描述: 编写一个 People 类,使其的实例具有监听事件、触发事件、解除绑定功能。(实例可能监听多个不同的事件,也可以去除监听事件)

class People {
  constructor(name) {
    this.name = name
  }
  
  sayHi() {
    console.log(`Hi, I am ${this.name}`)
  }
}


const say1 = greeting => {
  console.log(`${greeting}, nice meeting you.`)
}

const say2 = greeting => {
  console.log(`${greeting}, nice meeting you, too.`)
}

const jerry = new People('Jerry')
jerry.sayHi()


jerry.on('greeting', say1)
jerry.on('greeting', say2)

jerry.emit('greeting', 'Hi')


jerry.off('greeting', say1)
jerry.emit('greeting', 'Hi')

分析: 这道题主要靠面向对象的知识,事件监听与销毁

实现方案:

class People {
  constructor(name) {
    this.name = name
  }

  
  evtLoop = [] 

  
  on(evtType, func) {
    this.validate(func)
    this.evtLoop.push({ evtType, func })
  }

  
  emit(eventType, options) {
    this.evtLoop
        .filter(({ evtType }) => eventType === evtType)
        .forEach(item => item.func(options))
  }

  
  off(evtType, func) {
    this.validate(func)
    const idx = this.evtLoop.findIndex(item => item.evtType === evtType && item.func === func)
    idx < 0 && this.evtLoop.splice(idx, 1)
  }

  
  validate(func) {
    if (typeof func !== 'function') {
      throw new Error('监听事件必须是一个函数,请重新输入')
    }
  }

  sayHi() {
    console.log(`Hi, I am ${this.name}`)
  }
}

题目二

描述: 完成 sleep 函数,可以达到下面的效果

const sleep = duration => {
  
}

const anyFunc = async () => {
  console.log('123') 
  await sleep(300) 
  console.log('456') 
}

分析: 这题主要考查 js 的事件机制

实现方案: (这题有多种实现方案)

const sleep = duration => {
  
  return new Promise(resolve => setTimeout(resolve, duration))
}

题目三

描述: 完成 deepGet 函数,给它传入一个对象和字符串,字符串表示对象深层属性的获取路径,可以深层次获取对象内容

const deepGet = (obj, prop) => {
  
}


deepGet(
  {
    school: {
      student: { name: 'Tomy' }
    }
  },
  'school.student.name'
) 

deepGet(
  {
    school: {
      students: [{ name: 'Tomy' }, { name: 'Lucy' }]
    }
  },
  'school.students[1].name'
) 


deepGet({ user: { name: 'Tomy' } }, 'user.age') 
deepGet({ user: { name: 'Tomy' } }, 'school.user.age') 

分析: 这题考察对数组以及对象方法的使用

实现方案:

const deepGet = (obj, prop) => {
  
  const keyArr = prop.split('.').map(item => item)

  const reducer = (acc, cur) => {
    
    const objKey = cur.includes('[') && cur.replaceAll(/[\[?=0-9\]$]/gi, '')
    if (Array.isArray(acc[objKey])) {
      
      cur = cur.replaceAll(/[^?=0-9]/gi, '')
      return acc[objKey][cur] || {}
    }
    return acc[cur] ? acc[cur] : {}
  }

  const result = keyArr.reduce(reducer, obj)
  return Object.keys(result).length ? result : undefined
}

题目四

描述: 完成 combo 函数,它接受任意多个单参函数(只接受一个参数的函数)作为参数,并且返回一个函数,它的作用:使得类似 f(g(h(a))) 这样的函数调用可以简写为 combo(f, g, h)(a)

const combo = () => {  

 }


const addOne = a => a + 1
const multiTwo = a => a * 2
const divThree = a => a / 3
const toString = a => a + ''
const split = a => a.split('')

split(toString(addOne(multiTwo(divThree(666)))))


const testForCombo = combo(split, toString, addOne, multiTwo, divThree)
testForCombo(666)

分析: 这道题主要考察高阶函数 - 柯里化函数的使用

实现方案:

const combo = (...funcs) => {
  
  funcs.length && funcs.reverse()
  return prop =>
    funcs.reduce((acc, cur) => {
      return cur(acc)
    }, prop)
}

题目五

描述: 有两个盘子分别放有 5 个和 7 个小球,两个朋友玩游戏:每个人轮流从两个盘子中拿小球,每人每次只能从其中一个盘子中拿,每次可以拿 1 个或者多个(不能一个都不拿),拿到最后一个小球的人算输,问开局先手和后手是否有必胜策略?如果有,请描述必胜策略。

分析: 这考题主要考察算法能力

实现方案: 假设: 1 号盘子: 5 个球, 2 号盘子 7 个球, 一个小朋友名为小 A,另一名为小 B

  1. 小 A 先手: 先拿 2 号盘子的 2 个小球,只要先手的一方尽量保证两个盘子的数量相同的就行,直至决胜轮

  2. 小 A 后手:暂未想到

posted @ 2022-06-29 13:37  chenSee  阅读(348)  评论(0编辑  收藏  举报