2024年前端最全前端常用工具库方法整理,计算机网络面试常见问题

文末

如果30岁以前,可以还不知道自己想去做什么的话,那30岁之后,真的觉得时间非常的宝贵,不能再浪费时间在一些碎片化的事情上,比如说看综艺,电视剧。一个人的黄金时间也就二,三十年,不能过得浑浑噩噩。所以花了基本上休息的时间,去不断的完善自己的知识体系,希望可以成为一个领域内的TOP。

同样是干到30岁,普通人写业务代码划水,榜样们深度学习拓宽视野晋升管理。

这也是为什么大家都说30岁是程序员的门槛,很多人迈不过去,其实各行各业都是这样都会有个坎,公司永远都缺的高级人才,只用这样才能在大风大浪过后,依然闪耀不被公司淘汰不被社会淘汰。

269页《前端大厂面试宝典》

包含了腾讯、字节跳动、小米、阿里、滴滴、美团、58、拼多多、360、新浪、搜狐等一线互联网公司面试被问到的题目,涵盖了初中级前端技术点。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

前端面试题汇总

JavaScript

/\*\*
 \* @param {Object} props
 \* @description 针对搜索值做统一处理
 \*/
export function convertParams(props) {
  const newParams = {};
  for (const index in props) {
    const item = props[index];
    const type = typeof item;
    if (item && type === 'string') {
       newParams[index] = item.replace(/\s/g, '');
     } if (Object.prototype.toString.call(item) === '[object Object]') {
        newParams[index] = convertParams(item)
      } else {
       newParams[index] = item;
     }
  }
  return newParams;
};

3.权限方法判断
/\*\*
 \* @param {Array|String} target 目标数组
 \* @param {Boolean} boolean 是否开启与的关系
 \* @description 判断当前用户是否在权限数据中
 \*/
export const authority = (target, boolean = false) => {
  const str = getProps('authority')  // 获取当前角色的所有权限码, 自定义获取;
  if (Array.isArray(target)) {
    if (boolean) {
      return target.every(item => roles.indexOf(item) > -1)
    }
    return target.some(item => roles.indexOf(item) > -1)
  }
  return str && str.indexOf(target) > -1
}

4.菜单栏权限控制是否显示
/\*\*
 \* 菜单栏权限显示隐藏/现在很多架构都是自动化路由,有现成的权限配置
 \* @param {Array} list 通过路由列表得到菜单列表
 \* @returns {Array}
 \* @description 通过用户权限控制的菜单列表(简易版)
 \*/
export const hasChild = (item) => {
  return item.children && item.children.length !== 0
}
export const getMenuByAside = (list) => {
  let res = [];
  list.forEach(item => {
    if (!item.access || authority(item.access)) {
      let obj = {
        title: item.title,
        index: item.index,
        icon: item.icon,
        access: item.access || undefined,
      }
      if (hasChild(item)) obj.children = getMenuByAside(item.children)
      if (hasChild(item) && authority(item.access)) {
        obj.children = getMenuByAside(item.children)
      }
      res.push(obj)
    }
  })
  return res
}

5.二维数组转换
/\*\*
 \* @param {Array} target 目标数组
 \* @param {String} key 目标key值
 \* @param {Boolean} boolean 是否需要数组转换
 \* @param {Object} option 匹配的对象key值,值:label/value/boolean
 \* @return {Array}
 \* @description 处理二维数组转一维数组匹配相关字段值
 \*/
export const reduceConcat = (target, key, boolean, option) => {
  let newTarget = [];
  const { label, bool, value } = option || {};
  newTarget = target && target.map(item => {
    if (boolean) {
      return item[key] && item[key].map(opt => ({
        ...item,
        [key]: opt,
        [label]: bool ? item[label][value] : item[label]
      }))
    }
    return item[key];
  }
  ).reduce((a, b) => a.concat(b));
  return newTarget || [];
}

7. 针对json数组对象的去重
/\*\*
 \* @param {Array} array 目标数据
 \* @param {String} label 匹配对象的字段
 \* @description 针对json数组对象的去重
 \*/
export function uniqueArray(array, label) {
  const obj = {};
  array = array.reduce((pre, next) => {
    !obj[next[label]] ? (obj[next[label]] = true && pre.push(next)) : "";
    return pre;
  }, []);
  return array;
}

6. 时间类
// 转换时间(时分秒)
/\*\*
 \* @param {Number|String} msd 转换时间戳
 \* @description 将时间戳转换成时分秒
 \*/
export function dealTimeToText(value) {
  let time = Math.floor(value / 1000)
  let h = Math.floor(Math.floor(time / 60) / 60)
  let min = Math.floor(time / 60) % 60
  let s = Math.round(time % 3600 % 60)
  if (h > 0) {
    return `${h}h${min}min${s}s`
  } else if (min > 0) {
    return `${min}min${s}s`
  } else {
    return `${s}s`
  }
}

  • 秒转时分秒
// 当天晚上23:59:59
const endTime = new Date(new Date(new Date().toLocaleDateString()).getTime() + 24 \* 60 \* 60 \* 1000 - 1);
// 一月时间
let start = new Date();
start.setMonth(start.getMonth() - 3);
return start.getTime() > time.getTime() || time.getTime() > endTime;

// 一周时间
const operateTime = [
  new Date(new Date().toLocaleDateString()).getTime() - 7 \* 24 \* 3600 \* 1000,
  new Date().setHours("23", "59", "59")
];

/\*\*
 \* @param {Number|String} value
 \* @description 秒数转化为时分秒
\*/
export const formatSeconds = (value) => {
  let secondTime = parseInt(value), minuteTime = 0, hourTime = 0;
  if (secondTime > 60) {
    minuteTime = parseInt(secondTime / 60);
    secondTime = parseInt(secondTime % 60);
    if (minuteTime > 60) {
      hourTime = parseInt(minuteTime / 60);
      minuteTime = parseInt(minuteTime % 60);
    }
  }
  let result = "" + parseInt(secondTime) + "秒";
  if (minuteTime > 0) {
    result = "" + parseInt(minuteTime) + "分" + result;
  }
  if (hourTime > 0) {
    result = "" + parseInt(hourTime) + "小时" + result;
  }
  return result;
}

  • 计算当前年龄
/\*\* 
 \* @param {String} dateTime 接收的日期eg: 1994-03-2 || 1569404854000
 \* @description 通用年龄计算公式
 \* \*/
import moment from 'moment';
export const getAgeYear = (dateTime) => {
  let reg = /^(\d{4})-(\d{1,2})-(\d{1,2})$/
  let time = !reg.test(dateTime) ? moment(dateTime, 'YYYY-MM-DD') : dateTime;
  let regexp = time.match(/^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2})$/);
  if (!regexp) return '';
  let date = new Date(regexp[1], regexp[3] - 1, regexp[4]);
  if (date.getFullYear() == regexp[1] && (date.getMonth() + 1) == regexp[3]
    && date.getDate() == regexp[4]) {
    let year = new Date().getFullYear();
    return year - regexp[1];
  }
}

  • 时间转换
/\*\*
 \* @param {Number} timelong 时间戳
 \* @param {String} format 格式类型
 \* @description 时间转换格式方法
 \* \*/
export const formatDate = (timelong, format = 'YYYY-MM-DD') => {
  function format2n(val) {
    return val < 10 ? '0' + '' + val : val;
  }
  let date = new Date(timelong);
  let year = date.getFullYear() + '';
  let month = format2n(date.getMonth() + 1) + '';
  let day = format2n(date.getDate()) + '';
  let hour = format2n(date.getHours()) + '';
  let minute = format2n(date.getMinutes()) + '';
  let second = format2n(date.getSeconds()) + '';
  return format.replace(/YYYY/g, year).replace(/YYY/g, year.slice(1)).replace(/YY/g, year.slice(2)).replace(/Y/g, year.slice(1)).replace(/MM/g, month).replace(/M/g, month.slice(1)).replace(/DD/g, day).replace(/D/g, day.slice(1)).replace(/hh/g, hour).replace(/h/g, hour.slice(1)).replace(/mm/g, minute).replace(/m/g, minute.slice(1)).replace(/ss/g, second).replace(/s/g, second.slice(1));
};

/\*\*
 \* @param {Number} timelong 时间戳
 \* @description 显示时间之前
 \* \*/

export const formatTimeAgo = (timelong) => {
  const nowtime = new Date().getTime();
  let diffValue = nowtime - timelong;
  const bs = (diffValue >= 0 ? '前' : '后'); // 判断时间点是在当前时间的 之前 还是 之后
  diffValue = Math.abs(diffValue);
  const targetDate = new Date(timelong)
  const nowDate = new Date(nowtime)
  const isSameYear = nowDate.getFullYear() === targetDate.getFullYear()
  if (diffValue < 6e4) { return '刚刚' } // 小于60秒,刚刚
  if (diffValue < 36e5) { return parseInt(diffValue / 6e4) + '分钟' + bs } // 小于1小时,按分钟
  if (diffValue < 864e5) { return parseInt(diffValue / 36e5) + '小时' + bs } // 小于1天按小时
  if (diffValue > 864e5 && diffValue < 1728e5) { return '昨天' } // 大于24小时小于48小时
  if (isSameYear) { return formatDate(timelong, 'MM-DD') } // 当前年份显示
  return formatDate(timelong, 'YYYY-MM-DD')
}

7.随机生成16进制颜色值,并改变状态
// 组件渲染后,500毫秒改变一次组件颜色
componentDidMount() {
	this.interval = setInterval(this.getRandomColor, 500);
}
getRandomColor = () => {
	this.setState({ 
		col: '#'+('00000'+(Math.random()\*0x1000000<<0).toString(16)).slice(-6),
	});
}

8.背景水印简易版
/\*\* 
 \* @param {str} 用户需要显示的水印信息
 \* @description 背景水印
 \* \*/
export function addWaterMarker(str) {
  const can = document.createElement('canvas');
  // const { body } = document;
  // body.appendChild(can);
  can.width = 200;
  can.height = 100;
  can.style.display = 'none';
  const cans = can.getContext('2d');
  cans.rotate(20 \* Math.PI / 180);
  cans.font = '16px Microsoft JhengHei';
  cans.fillStyle = 'rgba(17, 17, 17, 0.50)';
  cans.textAlign = 'left';
  cans.textBaseline = 'Middle';
  cans.fillText(str, can.width / 3, can.height / 2);
  return `url(${can.toDataURL('image/png')})`;
}

/\*\*
\* url转base64
\*/
urlToBase64(url) {
    return new Promise((resolve, reject) => {
      let canvas = document.createElement("canvas"),
        ctx = canvas.getContext("2d"),
        img = new Image();
      img.crossOrigin = "Anonymous";
      img.src = url;
      img.onload = () => {
        canvas.width = img.width;
        canvas.height = img.height;
        ctx.drawImage(img, 0, 0, img.width, img.height);
        let dataUrl = canvas.toDataURL("image/jpeg");
        canvas = null;
        resolve(dataUrl);
      };
    });
  },

9.常用code码统一报错提示
const codeMessage = {
  200: '服务器成功返回请求的数据。',
  201: '新建或修改数据成功。',
  202: '一个请求已经进入后台排队(异步任务)。',
  204: '删除数据成功。',
  400: '发出的请求有错误,服务器没有进行新建或修改数据的操作。',
  401: '用户没有权限(令牌、用户名、密码错误)。',
  403: '用户得到授权,但是访问是被禁止的。',
  404: '发出的请求针对的是不存在的记录,服务器没有进行操作。',
  406: '请求的格式不可得。',
  410: '请求的资源被永久删除,且不会再得到的。',
  422: '当创建一个对象时,发生一个验证错误。',
  500: '服务器发生错误,请检查服务器。',
  502: '网关错误。',
  503: '服务不可用,服务器暂时过载或维护。',
  504: '网关超时。',
};

10.原生ajax下载导出
/\*\*
 \* @param {String} url 下载URL地址
 \* @param {String|Number} downloadName 下载文件名称
 \* @Parma {type} 下载请求方法get||post
 \* @description 导出Excel文件
 \* \*/
import Vue from 'vue';
import moment from 'moment';
import Cookies from "js-cookie";
const that = new Vue();

export function fileDownload(url, downloadName = moment(new Date(), 'YYYY-MM-DD') + "任务监控数据表", option) {
  const { type, status, message, messageErr, params } = option;

  let fileName = downloadName + '.xlsx';

  let request = new XMLHttpRequest();

  status ? that.$message({
    type: 'warning',
    showClose: true,
    message: message || '已点击正在下载,请稍后...',
  }) : null;

  request.open(type || 'GET', url, true);

  request.setRequestHeader("Authorization", Cookies.get("user-token"));

  request.setRequestHeader(
    "Content-Type",
    params ? 'application/json' : "application/x-www-form-urlencoded; charset=UTF-8"
  );

  request.responseType = "blob";

  request.onload = function () {
    if (this.status === 200) {
      let blob = this.response;
      if (window.navigator.msSaveOrOpenBlob) {
        window.navigator.msSaveBlob(blob, fileName);
      } else {
        let downloadLink = document.createElement("a");
        let contentTypeHeader = request.getResponseHeader("Content-Type");
        downloadLink.href = window.URL.createObjectURL(
          new Blob([blob], { type: contentTypeHeader })
        );
        downloadLink.download = fileName;
        document.body.appendChild(downloadLink);
        downloadLink.click();
        document.body.removeChild(downloadLink);
        window.URL.revokeObjectURL(downloadLink.href)
      }
    } else {
      that.$message({
        type: 'error',
        showClose: true,
        message: messageErr ||'文件下载失败...',
      });
    }
  };
  request.send(params ? JSON.stringify(params) : void null);
}

10.file文件转码
const toDataUrl = (blob) => {
	return new Promise(resolve => {
		let file = new FileReader();
		file.onload = event => {
			resolve(event.target.result);
			};
		file.readAsDataURL(blob);
	});
},

11. url参数加密
export const Base64 = {
  //加密
  encode(params) {
    return btoa(encodeURIComponent(params).replace(/%([0-9A-F]{2})/g,
      function toSolidBytes(match, option) {
        return String.fromCharCode('0x' + option);
      }));
  },
  //解密
  decode(params) {
    return decodeURIComponent(atob(params.replace(/\s/g, '+')).split('').map(option => '%' + ('00' + option.charCodeAt(0).toString(16)).slice(-2)).join(''));
  }
}

\s : 表示 space ,空格
+: 一个或多个
^: 开始,^\s,以空格开始 结束,\s$,以空格结束
|:或者
/g:global, 全局

12. 背景水印
'use strict'

const watermark = {};

/\*\*
 \* @param {String} str // 要设置的水印的内容
 \* @param {String} container // 需要设置水印的容器 
 \*/
const id = '1.23452384164.123412415';

const setWatermark = (str, container) => {
  if (!container) return false;

  if (document.getElementById(id) !== null) { // 查看页面上有没有,如果有则删除
    const childelement = document.getElementById(id)
    childelement.parentNode.removeChild(childelement)
  }

  const containerWidth = container.offsetWidth // 获取父容器宽
  const containerHeight = Math.max(container.scrollHeight, document.body.clientHeight); // 获取父容器高
  container.style.position = 'relative' // 设置布局为相对布局

  const can = document.createElement('canvas') // 创建canvas元素(先制作一块背景图)
  can.width = 300 // 设置每一块的宽度
  can.height = 200 // 高度
  const cans = can.getContext('2d') // 获取canvas画布
  cans.rotate(20 \* Math.PI / 180) // 逆时针旋转π/9
  cans.font = '14px Microsoft JhengHei'; // 设置字体
  cans.fillStyle = 'rgba(17, 17, 17, 0.2)' // 设置字体的颜色
  cans.textAlign = 'left' // 文本对齐方式
  cans.textBaseline = 'Middle' // 文本基线
  cans.fillText(str, can.width / 3, can.height / 2); // 绘制文字

  const div = document.createElement('div') // 创建一个div元素
  div.id = id // 设置id
  div.style.pointerEvents = 'none' // 取消所有事件
  div.style.top = '0px'
  div.style.left = '0px'
  div.style.position = 'absolute'
  div.style.zIndex = '10000'
  div.style.width = containerWidth + 'px'
  div.style.height = containerHeight + 'px'
  div.style.background = 'url(' + dataURLtoBlob(can.toDataURL('image/png')) + ')'
  container.appendChild(div) // 追加到页面
  return id
}

function dataURLtoBlob(dataurl) {
  let arr = dataurl.split(',');
  let mime = arr[0].match(/:(.\*?);/)[1];
  let bstr = atob(arr[1]);
  let n = bstr.length;
  let u8arr = new Uint8Array(n);
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n);
  }
  return URL.createObjectURL(new Blob([u8arr], { type: mime }));
}

let _interval = null;

// 该方法只允许调用一次
watermark.set = (str, container) => {
  let id = setWatermark(str, container)
  _interval = setInterval(() => {
    if (document.getElementById(id) === null) {
      id = setWatermark(str, container)
    }
  }, 500)
  window.onresize = () => {  // 监听页面大小的变化
    setWatermark(str, container)
  }
}

export default watermark;

12. 随机生成颜色
  getArrRandomly() {
    const tagsColor = ["info", "warning", "danger", ""];
    var colorIndex = Math.floor(Math.random() \* tagsColor.length);
    var color = tagsColor[colorIndex];
    tagsColor.splice(colorIndex, 1);
    return color;
  },

13. 倒计时
startTime(bolean, endTimer) {
    let minute = 0
    let second = 0
    const that = this
    if (endTimer) {
      ;[minute, second] = this.callinTime.split(':')
      minute = Number(minute)
      second = Number(second)
    }
    if (bolean === true) {
      that.timer = setInterval(() => {
        if (second >= 0) {
          second = second + 1
        }
        if (second >= 60) {
          second = 0
          minute = minute + 1
        }
        if (endTimer && that.callinTime === endTimer) {
          this.suspendStatus = false
          this.callinTime = '00:00'
          return clearInterval(that.timer)
        }
        that.callinTime =
          (minute < 10 ? '0' + minute : minute) +
          ':' +
          (second < 10 ? '0' + second : second)
      }, 1000)
    } else {
      clearInterval(that.timer)
    }
  }

14. 金额转换
function toThousands(num) {
  if (num && num.toString().length > 4) {
    const result = num.toString().replace(/(\d)(?=(?:\d{4})+$)/g, '$1.')
    return Number(result).toFixed(1) + 'w'
  }
  return num
}

css

1,盒模型
2,如何实现一个最大的正方形
3,一行水平居中,多行居左
4,水平垂直居中
5,两栏布局,左边固定,右边自适应,左右不重叠
6,如何实现左右等高布局
7,画三角形
8,link @import导入css
9,BFC理解

js

1,判断 js 类型的方式
2,ES5 和 ES6 分别几种方式声明变量
3,闭包的概念?优缺点?
4,浅拷贝和深拷贝
5,数组去重的方法
6,DOM 事件有哪些阶段?谈谈对事件代理的理解
7,js 执行机制、事件循环
8,介绍下 promise.all
9,async 和 await,
10,ES6 的 class 和构造函数的区别
11,transform、translate、transition 分别是什么属性?CSS 中常用的实现动画方式,
12,介绍一下rAF(requestAnimationFrame)
13,javascript 的垃圾回收机制讲一下,
14,对前端性能优化有什么了解?一般都通过那几个方面去优化的?

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

return num
}




#### css

1,盒模型
2,如何实现一个最大的正方形
3,一行水平居中,多行居左
4,水平垂直居中
5,两栏布局,左边固定,右边自适应,左右不重叠
6,如何实现左右等高布局
7,画三角形
8,link @import导入css
9,BFC理解


[外链图片转存中...(img-5CnsyutH-1715526314585)]

#### js

1,判断 js 类型的方式
2,ES5 和 ES6 分别几种方式声明变量
3,闭包的概念?优缺点?
4,浅拷贝和深拷贝
5,数组去重的方法
6,DOM 事件有哪些阶段?谈谈对事件代理的理解
7,js 执行机制、事件循环
8,介绍下 promise.all
9,async 和 await,
10,ES6 的 class 和构造函数的区别
11,transform、translate、transition 分别是什么属性?CSS 中常用的实现动画方式,
12,介绍一下rAF(requestAnimationFrame)
13,javascript 的垃圾回收机制讲一下,
14,对前端性能优化有什么了解?一般都通过那几个方面去优化的?


[外链图片转存中...(img-KyrveDu1-1715526314586)]

**[开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】](https://bbs.csdn.net/forums/4304bb5a486d4c3ab8389e65ecb71ac0)**



  • 10
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值