记一次今日头条前端笔试
- 作者:Bougie
- 创建于:2018-07-17
- 更新于:2023-03-09
# 第一题
- 点击表格单元格时输出单元格中的内容,表格的数据是异步获取的。
// 事件委托
document.querySelector('table').addEventListener('click', (event) => {
if (event.target.tagName === 'td') {
alert(event.target.innerHTML)
}
})
// jQuery
$('table').on('click', 'td', function () {
alert($(this).html())
})
# 第二题
- 对原码、反码、补码的理解,以及他们之间如何相互转换。
前端的同学看到这题肯定无语了,感觉大厂还是喜欢问一些原理和底层的东西啊,即使你工作中可能根本用不到。网上搜到的头条面试也有同学被问到“http 工作原理”、“ajax 原理”、“javascript 基本类型和引用类型内存分配有什么区别”等等。
# 第三题
- 以下代码打印出什么
var x = 1
var func = function () {
console.log(this.x)
}
var obj1 = { x: 1 }
var obj2 = { x: 2 }
var obj3 = { x: 3 }
var func1 = func.bind(obj1)
func1()
var func2 = func.bind(obj1).bind(obj2)
func2()
var func3 = func.bind(obj1).bind(obj2).bind(obj3)
func3()
答案是打印出三个 1。
# 第四题
- 实现以下布局,当页面内容超出浏览器窗口时,Footer 接在 Content 后面,未超出时 Footer 固定在页面底部。尽可能多的列出布局方案。
感觉题意描述不是很清晰啊,没说只能用 css 还是 css 和 js 都能用,也没说兼容性要求。基础好的同学估计能想出一万种方法。我当时用 css 写了两种方法。
方法一:
<!DOCTYPE html>
<html lang="en">
<head>
<style>
body {
margin: 0;
padding: 0;
}
.top-part {
min-height: calc(100vh - 150px);
}
header {
height: 100px;
background: red;
}
content {
display: block;
background: blue;
height: 500px;
}
footer {
height: 150px;
background: green;
}
</style>
</head>
<body>
<div class="top-part">
<header></header>
<content></content>
</div>
<footer></footer>
</body>
</html>
方法二:
<!DOCTYPE html>
<html lang="en">
<head>
<style>
body {
margin: 0;
padding: 0;
}
.bottom-part {
min-height: calc(100vh - 100px);
display: flex;
flex-direction: column;
justify-content: space-between;
}
header {
height: 100px;
background: red;
}
content {
display: block;
background: blue;
height: 500px;
}
footer {
height: 150px;
background: green;
}
</style>
</head>
<body>
<header></header>
<div class="bottom-part">
<content></content>
<footer></footer>
</div>
</body>
</html>
方案一可以兼容到 IE9,方案二由于使用了 flex 布局,只能兼容到 IE10。
# 第五题
- 日期转化函数。输入一个日期对象或时间戳或日期字符串,若它与当前时间相差少于 1 分钟,则输出“刚刚”;若小于两小时,则输出“xxx 分钟前”;若大于两小时,则输出“xxx 小时前”;若大于一天,则输出"xxx 天前";大于两天,则直接输出日期。
转化为时间戳再比较就行了:
function dateTransform(date) {
date = new Date(date).getTime()
let now = new Date().getTime()
let interval = (now - date) / 1000 / 60
// 这里写一系列的if else判断就行了...
}
# 第六题
- 把
1234567890.12
转化为123,456,789.12
。要求用 js 的方法和正则的方法。
对于外行人来说,程序员的正则就像道士的鬼画符。可惜我正则学的稀烂,当时直接把正则给 pass 掉了。于是开始用 js 的方法转化,当时想的是先取出小数部分,再对整数部分进行递归。结束后 Google 一下竟然发现数字还有toLocaleString
方法,可以直接转换,有点想骂娘的心情了。附上标准答案:
// js方法
function numberTransform(num) {
return num.toLocaleString()
}
// 正则方法
function numberTransform(num) {
num = num.toString()
let arr = num.split('.')
return arr[0].replace(/(\d)(?=(?:\d{3})+$)/g, '$1,') + '.' + arr[1]
}
# 第七题
- 实现一个
Event
类,继承这个类的子类都有on
、once
、trigger
、remove
方法。
当时看到这题是懵比的,因为它题干就这么多。
class Event {
constructor() {}
on() {}
once() {}
trigger() {}
remove() {}
}
按照题干的意思是这样就可以了。但是它这四个方法又像发布订阅模式的事件中心,于是我就把它改成了这样:
class Event {
constructor() {
this.evList = {}
}
on(evName, callback) {
Reflect.set(this.evList, callback)
}
once(evName, param) {
this.trigger(evName, param)
this.remove(evName)
}
trigger(evName, param) {
let fn = Reflect.get(this.evList, evName)
if (!fn) return
fn.call(null, param)
}
remove(evName) {
Reflect.deleteProperty(this.evList, evName)
}
}
# 第八题
- 把一堆乱七八糟的字符串转化为数组。
没说用啥转化,转化后数组中还有字符串中不存在的字符。完全莫名其妙的题。
# 总结
对今日头条这种笔试方式略感失望啊,出题是用的牛客网这个平台,题目描述也写的不清不明,题目类型全部是问答题,有的明明是编程题。感觉自己被当成效率招聘的试验品了。