记一次今日头条前端面试
最近公司部门被裁了,让我这个刚刚毕业一年不到的人情何以堪啊。硬着头皮出去面试吧!
在此记录一下今日头条面试中印象比较深刻的问题,问题顺序已打乱。
一、实现Bind函数
其实本来不是考查这个的,仅仅是考查bind的用法。后来题目做出来面试官又继续问如何实现bind。下面是参考MDN的polyfill写出来的代码:
if(!Function.prototype.bind){ Function.prototype.bind = function(context){ // 首先判断this是不是function if(typeof this !== 'function'){ // 抛出错误 } var _this = this, fNOP = function(){}, // 用于后面维护原型关系 args = Array.prototype.slice.call(arguments, 1), // 取出bind收到的参数,除去第一个作为上下文的参数并保存 fBound = function(){ _this.call(context, args.concat(Array.prototype.slice.call(arguments))) // 将bind接收的的参数和实际接收到的参数相连接 }; // 维护原型关系 if(this.prototype){ fNOP.prototype = this.prototype; fBound.prototype = new fNOP; } return fBound; } }
二、实现节流函数
有一个高频操作会让函数迅速执行很多次,需要按照下面的时间线图来实现一个节流函数。
节流函数示意图
图是word画的,微信截的图,凑合看吧...图中每一个断点都代码触发了一次函数,但是触发函数时只在奇数时执行,偶数时不执行,断点间的时间间隔为50ms。
根据题意需要的是一个节流函数。刚开始时我是这么实现的:
var throttle = function(fn){ var timer = null; return function(){ var args = arguments, context = this; clearTimeout(timer); timer = setTimeout(function(){ fn.call(context, args) }, 100) } } 这跟javascript高级程序设计中的实现方式差不多,其实严格来说这种实现方式并不叫节流函数,而是防抖函数:短时间内多次调用同一函数,只执行最后一次调用。 下面是改进:var throttle = function(fn){ var timer = null; return function(){ var args = arguments, context = this; if(!timer){ timer = setTimeout(function(){ timer = null; fn.call(context, args) }, 100); } } } 如此一来这个功能基本上就可以实现了,但是仍有一个问题,第一次调用的时候函数并没有执行,而是直接从第三次调用开始执行的,那么我们再改进一下,加一个第一次调用时的哨兵即可:var throttle = function(fn){ var timer = null, first = true; return function(){ var args = arguments, context = this; if(first){ first = false; fn.call(context, args) } if(!timer){ timer = setTimeout(function(){ timer = null; fn.call(context, args) }, 100); } } }
三、穷举组合
实现一个函数,给三个参数,data是整形数组,m和sum都是一个整数,从data中取出n个整数,使它们的和为sum,求出一种组合即可。
我的思路是穷举data中的n个key的组合,假设data有6(n)个元素,从中取出3(m)个数,那么它key的组合就有:[0,1,2]、[0,1,3]、[0,1,4]、[0,1,5]、[0,2,3]、[0,2,4]、[0,2,5]、...、[3,4,5]
列出它的所有组合就好办了,直接用这些key去data里面取数,如果找到答案就退出程序。
下面仅给出穷举组合的算法,为了简单,相关参数写死并忽略全局污染:
// 数组a用于存放key的组合,data并没有出现,只给出data元素个数nvar a=[0,1,2], oldA = [],n = 6, len = a.length;function listArr(key){ let same = true for(let i = 0 ; i < len ; i++){ if(a[i] !== oldA[i]){ same = false break } } if(!same){ console.log(a) oldA = Array.prototype.slice.call(a) } }function list(currentKey, initValue){ if(currentKey >= len || initValue >= n){ return } for(let v = initValue ; v <= n + currentKey - len ; v++){ a[currentKey] = v arguments.callee(currentKey+1, v+1) listArr(currentKey); } } list(0,0)
当然不止这些题目,我这里只是列出了一些我答得不好和根本没有答出来的题目(逃),面试的结果应该是黄了。今天回头一想其实都还是可以做出来的,只是平时练得太少,心态也有点问题。多多复习,希望接下来的面试顺利吧!
作者:钟泽方
链接:https://www.jianshu.com/p/8199bb710d40
共同学习,写下你的评论
评论加载中...
作者其他优质文章