字节跳动前端笔试

大概是做炸了... 不能跳出去调试和搜索,差不多废了我最厉害的两个能力 ?

一共 8 道问答题,没有办法调试的话果然会错很多。下面的都是调试好了的

1.字符串分割

(str) => {
    let s = str.split('\n')
    s.forEach((line,index) => s[index]=line.split(/\s+/g))
    return s
}
(str) => {
    let s = str.split('\n')
    s.forEach((line,index) => s[index]=line.split(/\s+/g))
    return s
}

2.格式化数字

//non-RegExp
((str) => {
    let s = str.split('.')
    let ret = ''
    let len = s[0].length
    for(let i = 0; i<len; i++) {
        ret += s[0][i]
        if(i % 3 == len % 3 - 1 && i != len - 1) {
            ret += ','
        }
    }
    ret += '.' + s[1]
    return ret
})('1234567890.987654321')
 
//RegExp
((str) => str.replace(/(?=(\B\d{3})+\.)/g, ','))('1234567890.987654321')
//non-RegExp
((str) => {
    let s = str.split('.')
    let ret = ''
    let len = s[0].length
    for(let i = 0; i<len; i++) {
        ret += s[0][i]
        if(i % 3 == len % 3 - 1 && i != len - 1) {
            ret += ','
        }
    }
    ret += '.' + s[1]
    return ret
})('1234567890.987654321')
 
//RegExp
((str) => str.replace(/(?=(\B\d{3})+\.)/g, ','))('1234567890.987654321')

3.时间转时间描述(几分钟前、几小时前、超过两天返回准确时间)

这大概是唯一自己之前遇到过的东西了,计算当前时间戳和给定时间戳的差然后 if-else 就可以。可惜的是不记得 Date 转时间戳的方法了(应该是Date.valueOf()),这里贴的是以前写的。

timeDesctiption(timestamp) {
  var now = (new Date()).valueOf()
  var delta = (now - timestamp) / 1000
  if (delta < 60) return '刚刚'
  else if (delta < 3600) return parseInt(delta / 60) + '分钟前'
  else if (delta < 86400) return parseInt(delta / 3600) + '小时前'
  else return parseInt(delta / 86400) + '天前'
}
timeDesctiption(timestamp) {
  var now = (new Date()).valueOf()
  var delta = (now - timestamp) / 1000
  if (delta < 60) return '刚刚'
  else if (delta < 3600) return parseInt(delta / 60) + '分钟前'
  else if (delta < 86400) return parseInt(delta / 3600) + '小时前'
  else return parseInt(delta / 86400) + '天前'
}

4.实现 Event 类,具有 on, once, off, trigger 方法

class Event{
  handlers = {}
  on(e, handler) {
    if(this.handlers[e]) this.handlers[e].push(handler)
    else this.handlers[e] = [handler]
  }
  off(e, handler) {
    if(!this.handlers[e]) return
    this.handlers[e].forEach((h,i) => {
      if(h === handler) {
        this.handlers[e].splice(i, 1)
        return
      }
    })
  }
  once(e, handler) {
    let wrapper = (param) => {
      handler(param)
      this.off(e, wrapper)
    }
    this.on(e, wrapper)
  }
  trigger(e, param) {
    this.handlers[e].forEach(h => h(param))
  }
}
class Event{
  handlers = {}
  on(e, handler) {
    if(this.handlers[e]) this.handlers[e].push(handler)
    else this.handlers[e] = [handler]
  }
  off(e, handler) {
    if(!this.handlers[e]) return
    this.handlers[e].forEach((h,i) => {
      if(h === handler) {
        this.handlers[e].splice(i, 1)
        return
      }
    })
  }
  once(e, handler) {
    let wrapper = (param) => {
      handler(param)
      this.off(e, wrapper)
    }
    this.on(e, wrapper)
  }
  trigger(e, param) {
    this.handlers[e].forEach(h => h(param))
  }
}

5.谈谈你对原码、反码、补码的理解以及转换方式

6.布局:当 content 超出屏幕长度时隐藏 footer, 当 content 不足以填充屏幕时 footer 固定在页面底部

  1. content 外面包一层 container min-height: 100%; 再把 footer 的 margin-bottom 设为负
  2. js 检测高度 scrollHeight 设置 CSS

7.bind 输出

var v = 1
function a(){
  console.log(this.v)
}
let f = a.bind({v: 1})
f()
f = a.bind({v: 1}).bind({v: 2})
f()
f = a.bind({v: 1}).bind({v: 2}).bind({v: 3})
f()
var v = 1
function a(){
  console.log(this.v)
}
let f = a.bind({v: 1})
f()
f = a.bind({v: 1}).bind({v: 2})
f()
f = a.bind({v: 1}).bind({v: 2}).bind({v: 3})
f()

输出为1 1 1,因为后面的两个 bind 影响的是前面 bind 形成的函数的 this,但是第一个 bind 并不会使用到 this,而是传递使用参数 {v: 1} 作为 a 的 this。

8.有一个表格,内容是异步加载渲染的,要求实现点击 td 输出内容

没太看懂这道题。。。估计是问怎么获取 td 所在的行列。vue 的话 v-for 自带 index 传递给 v-on:click="handle(row, column)" (行 index: row, 列 index: column)。或者也可以在渲染时给每个 td 绑不同的函数。

另外 Google Analytics 显示我的博客昨天下午被访问了,那些应该是字节跳动的面试官吧......

Loading New Comments...