2021前端面试之JavaScript手写题(三)

悠悠 2022-10-17 00:43 256阅读 0赞

1.如何实现数组的随机排序?

  1. let arr = [2,3,454,34,324,32]
  2. arr.sort(randomSort)
  3. function randomSort(a, b) {
  4. return Math.random() > 0.5 ? -1 : 1;
  5. }

2.写一个通用的事件侦听器函数。

  1. const EventUtils = {
  2. // 视能力分别使用dom0||dom2||IE方式 来绑定事件
  3. // 添加事件
  4. addEvent: function(element, type, handler) {
  5. if (element.addEventListener) {
  6. element.addEventListener(type, handler, false);
  7. } else if (element.attachEvent) {
  8. element.attachEvent("on" + type, handler);
  9. } else {
  10. element["on" + type] = handler;
  11. }
  12. },
  13. // 移除事件
  14. removeEvent: function(element, type, handler) {
  15. if (element.removeEventListener) {
  16. element.removeEventListener(type, handler, false);
  17. } else if (element.detachEvent) {
  18. element.detachEvent("on" + type, handler);
  19. } else {
  20. element["on" + type] = null;
  21. }
  22. },
  23. // 获取事件目标
  24. getTarget: function(event) {
  25. return event.target || event.srcElement;
  26. },
  27. // 获取 event 对象的引用,取到事件的所有信息,确保随时能使用 event
  28. getEvent: function(event) {
  29. return event || window.event;
  30. },
  31. // 阻止事件(主要是事件冒泡,因为 IE 不支持事件捕获)
  32. stopPropagation: function(event) {
  33. if (event.stopPropagation) {
  34. event.stopPropagation();
  35. } else {
  36. event.cancelBubble = true;
  37. }
  38. },
  39. // 取消事件的默认行为
  40. preventDefault: function(event) {
  41. if (event.preventDefault) {
  42. event.preventDefault();
  43. } else {
  44. event.returnValue = false;
  45. }
  46. }
  47. };

3.使用迭代的方式实现 flatten 函数。

  1. var arr = [1, 2, 3, [4, 5], [6, [7, [8]]]]
  2. /** * 使用递归的方式处理 * wrap 内保
  3. 存结果 ret * 返回一个递归函数 **/
  4. function wrap() {
  5. var ret = [];
  6. return function flat(a) {
  7. for (var item of
  8. a) {
  9. if (item.constructor === Array) {
  10. ret.concat(flat(item))
  11. } else {
  12. ret.push(item)
  13. }
  14. }
  15. return ret
  16. }
  17. }
  18. console.log(wrap()(arr));

4.怎么实现一个sleep

  1. sleep函数作用是让线程休眠,等到指定时间在重新唤起。
  2. function sleep(delay) {
  3. var start = (new Date()).getTime();
  4. while ((new Date()).getTime() - start < delay) {
  5. continue;
  6. }
  7. }
  8. function test() {
  9. console.log('111');
  10. sleep(2000);
  11. console.log('222');
  12. }
  13. test()

5.实现正则切分千分位(10000 => 10,000)

  1. //无小数点
  2. let num1 = '1321434322222'
  3. num1.replace(/(\d)(?=(\d{3})+$)/g,'$1,')
  4. //有小数点
  5. let num2 = '342243242322.3432423'
  6. num2.replace(/(\d)(?=(\d{3})+\.)/g,'$1,')
  7. 复制代码
  8. 27.对象数组去重
  9. 输入:
  10. [{a:1,b:2,c:3},{b:2,c:3,a:1},{d:2,c:2}]
  11. 输出:
  12. [{a:1,b:2,c:3},{d:2,c:2}]

首先写一个函数把对象中的key排序,然后再转成字符串
遍历数组利用Set将转为字符串后的对象去重

  1. function objSort(obj){
  2. let newObj = {}
  3. //遍历对象,并将key进行排序
  4. Object.keys(obj).sort().map(key => {
  5. newObj[key] = obj[key]
  6. })
  7. //将排序好的数组转成字符串
  8. return JSON.stringify(newObj)
  9. }
  10. function unique(arr){
  11. let set = new Set();
  12. for(let i=0;i<arr.length;i++){
  13. let str = objSort(arr[i])
  14. set.add(str)
  15. }
  16. //将数组中的字符串转回对象
  17. arr = [...set].map(item => {
  18. return JSON.parse(item)
  19. })
  20. return arr
  21. }

6.解析 URL Params 为对象

  1. let url = 'http://www.domain.com/?user=anonymous&id=123&id=456&city=%E5%8C%97%E4%BA%AC&enabled';
  2. parseParam(url)
  3. /* 结果
  4. { user: 'anonymous',
  5. id: [ 123, 456 ], // 重复出现的 key 要组装成数组,能被转成数字的就转成数字类型
  6. city: '北京', // 中文需解码
  7. enabled: true, // 未指定值得 key 约定为 true
  8. }
  9. */
  10. function parseParam(url) {
  11. const paramsStr = /.+\?(.+)$/.exec(url)[1]; // 将 ? 后面的字符串取出来
  12. const paramsArr = paramsStr.split('&'); // 将字符串以 & 分割后存到数组中
  13. let paramsObj = {};
  14. // 将 params 存到对象中
  15. paramsArr.forEach(param => {
  16. if (/=/.test(param)) { // 处理有 value 的参数
  17. let [key, val] = param.split('='); // 分割 key 和 value
  18. val = decodeURIComponent(val); // 解码
  19. val = /^\d+$/.test(val) ? parseFloat(val) : val; // 判断是否转为数字
  20. if (paramsObj.hasOwnProperty(key)) { // 如果对象有 key,则添加一个值
  21. paramsObj[key] = [].concat(paramsObj[key], val);
  22. } else { // 如果对象没有这个 key,创建 key 并设置值
  23. paramsObj[key] = val;
  24. }
  25. } else { // 处理没有 value 的参数
  26. paramsObj[param] = true;
  27. }
  28. })
  29. return paramsObj;
  30. }

7.模板引擎实现

  1. let template = '我是{
  2. {name}},年龄{
  3. {age}},性别{
  4. {sex}}';
  5. let data = {
  6. name: '姓名',
  7. age: 18
  8. }
  9. render(template, data); // 我是姓名,年龄18,性别undefined
  10. 复制代码
  11. function render(template, data) {
  12. const reg = /\{\{(\w+)\}\}/; // 模板字符串正则
  13. if (reg.test(template)) { // 判断模板里是否有模板字符串
  14. const name = reg.exec(template)[1]; // 查找当前模板里第一个模板字符串的字段
  15. template = template.replace(reg, data[name]); // 将第一个模板字符串渲染
  16. return render(template, data); // 递归的渲染并返回渲染后的结构
  17. }
  18. return template; // 如果模板没有模板字符串直接返回
  19. }

8.转化为驼峰命名

  1. var s1 = "get-element-by-id"
  2. // 转化为 getElementById
  3. 复制代码
  4. var f = function(s) {
  5. return s.replace(/-\w/g, function(x) {
  6. return x.slice(1).toUpperCase();
  7. })
  8. }

9.查找字符串中出现最多的字符和个数

  1. 例: abbcccddddd -> 字符最多的是d,出现了5
  2. let str = "abcabcabcbbccccc";
  3. let num = 0;
  4. let char = '';
  5. // 使其按照一定的次序排列
  6. str = str.split('').sort().join('');
  7. // "aaabbbbbcccccccc"
  8. // 定义正则表达式
  9. let re = /(\w)\1+/g;
  10. str.replace(re,($0,$1) => {
  11. if(num < $0.length){
  12. num = $0.length;
  13. char = $1;
  14. }
  15. });
  16. console.log(`字符最多的是${char},出现了${num}次`);

10.图片懒加载

  1. let imgList = [...document.querySelectorAll('img')]
  2. let length = imgList.length
  3. const imgLazyLoad = function() {
  4. let count = 0
  5. return (function() {
  6. let deleteIndexList = []
  7. imgList.forEach((img, index) => {
  8. let rect = img.getBoundingClientRect()
  9. if (rect.top < window.innerHeight) {
  10. img.src = img.dataset.src
  11. deleteIndexList.push(index)
  12. count++
  13. if (count === length) {
  14. document.removeEventListener('scroll', imgLazyLoad)
  15. }
  16. }
  17. })
  18. imgList = imgList.filter((img, index) => !deleteIndexList.includes(index))
  19. })()
  20. }
  21. // 这里最好加上防抖处理
  22. document.addEventListener('scroll', imgLazyLoad)

总结一下

面试前要精心做好准备,简历上写的知识点和原理都需要准备好,项目上多想想难点和亮点,这是面试时能和别人不一样的地方。

还有就是表现出自己的谦虚好学,以及对于未来持续进阶的规划,企业招人更偏爱稳定的人。

万事开头难,但是程序员这一条路坚持几年后发展空间还是非常大的,一切重在坚持。

为了帮助大家更好更高效的准备面试,特别整理了《前端工程师面试手册》电子稿文件。

621960a57eb42479e02d6d64c0c81891.png

5230c48fd0fcb265f3401a21603bda2b.png

前端面试题汇总

42728594459506983a38ca2b86545fc6.png

JavaScript

7796de226b373d068d8f5bef31e668ce.png

性能

d7f6750332c78eb27cc606540cdce3b4.png

linux

ed368cc25284edda453a4c6cb49916ef.png

前端资料汇总

6e0ba223f65e063db5b1b4b6aa26129a.png

完整版PDF资料免费分享,只需你点赞支持,动动手指点击此处就可免费领取了。

前端工程师岗位缺口一直很大,符合岗位要求的人越来越少,所以学习前端的小伙伴要注意了,一定要把技能学到扎实,做有含金量的项目,这样在找工作的时候无论遇到什么情况,问题都不会大。

发表评论

表情:
评论列表 (有 0 条评论,256人围观)

还没有评论,来说两句吧...

相关阅读