福 利
秋招在即,进入尾声了。也不管秋招还是什么,每时每刻都有着一批批的求职者在奔波,面试题也始终是求职者的一味定心的药剂,让你成竹在胸,让你对答如流,让你更加的优秀完美。看到本篇皆是缘分,祝你早日去到理想的公司。
满满干货,记得收藏
JavaScript篇
用js能做的东西很多,这些你了解吗?面试可以让你装逼,工作中让你轻松的js方法,再三叮嘱记得收藏。1. JS打乱数组(洗牌算法)
function getArrRandomly(arr) { var len = arr.length; for (var i = 0; i < len; i++) { var randomIndex = Math.floor(Math.random()*(len-i));//这里一定要注意,后面不管是(i+1)还是(len-i),它们是时变的。 var itemAtIndex = arr[randomIndex]; arr[randomIndex] = arr[i]; arr[i] = itemAtIndex; } return arr;}
2. JS预编译
js预编译实现过程:
1.创建GO/AO对象
2.找形参和变量声明,将变量和形参名作为AO属性名,值为undefined
3.将实参值和形参统一
4.在函数体里面找函数声明,值赋予函数体
3. JS ajax (这里用get方法,做一个例子,post的类似只是传参方式不同)
//步骤一:创建异步对象var ajax = new XMLHttpRequest();//步骤二:设置请求的url参数,参数一是请求的类型,参数二是请求的url,可以带参数,动态的传递参数starName到服务端ajax.open('get','getStar.php?starName='+name);//步骤三:发送请求ajax.send();//步骤四:注册事件 onreadystatechange 状态改变就会调用ajax.onreadystatechange = function () {if (ajax.readyState==4 &&ajax.status==200) { //步骤五 如果能够进到这个判断 说明 数据 完美的回来了,并且请求的页面是存在的 console.log(ajax.responseText);//输入相应的内容 }}
4. 节流函数
/** * 节流:动作绑定事件,动作发生后一段时间后触发事件, * 在这段时间内,如果动作有发生了,则无视该动作,直到时间执行完后,才能重新触发 * 原理:在每次函数执行前先判断是否存在定时器,存在则跳过本次执行,否则设置定时器 */function throttle(fn, wait) { var pre = Date().now(); return function () { var now = Date.now(); if (now - prev >= wait) { fun.apply(this, arguments); pre = Date.now(); } };}
5. 防抖函数
/** * 动作绑定事件, * 动作发生后在一定时间内触发事件, * 在这段时间内,如果动作发生了,则重新等待一定时间在触发事件 * * 原理:在每次函数执行前先清空上一次设置的定时器 * */function debounce(fn, wait) { var timer; return function () { if (timer) { clearTimeout(timer); } timer = setTimeout(() => { fn.apply(this, arguments); }, wait); };}
6. JS bind 实现
if (!Function.prototype.bind) { Function.prototype.bind = function () { var self = this, // 保存原函数 context = [].shift.call(arguments), // 保存需要绑定的this上下文 args = [].slice.call(arguments); // 剩余的参数转为数组 return function () { // 返回一个新函数 self.apply(context,[].concat.call(args, [].slice.call(arguments))); } }}
7. JS map 实现
Array.prototype.map = function () { var arr = this, result = []; var [fn, thisValue] = Array.prototype.slice.call(arguments); for (var i = 0; i < arr.length; i++) { result.push(fn.call(thisValue, arr[i], i, arr)) } return result;}
8. IndexOf实现
function ArrayIndexOf(arr,value,n){ var i=isNaN(n)?0:n;//有第三参时 i=(i<0)?arr.length+i:i;//第三参为负数时 for(i;i if(arr[i]===value){return i;} }return -1;}
9. 懒加载
let lazyImages = [...document.querySelectorAll('.lazy-image')]let inAdvance = 300 // 自定义一个高度,当距离300px到达图片时加载function lazyLoad() { lazyImages.forEach(image => { if (image.offsetTop < window.innerHeight + window.pageYOffset + inAdvance) { // 距离xxpx时加载图片 image.src = image.dataset.src image.onload = () => image.classList.add('loaded') } })}lazyLoad()window.addEventListener('scroll', _.throttle(lazyLoad, 16)) // 用到了lodash的节流函数window.addEventListener('resize', _.throttle(lazyLoad, 16))
10. JS实现Promise
class PromiseClone { constructor (process) { this.status = 'pending' this.msg = '' process(this.resolve.bind(this), this.reject.bind(this)) return this } resolve (val) { this.status = 'fulfilled' this.msg = val } reject (err) { this.status = 'rejected' this.msg = err } then (fufilled, reject) { if(this.status === 'fulfilled') { fufilled(this.msg) } if(this.status === 'rejected') { reject(this.msg) } }}
11. Jsonp跨域
function Jsonp(url, param, callback) { var script = document.createElement('script') param = {...param, callback} var arr = []; for(var key in param) { arr.push(`${key}=${param[key]}`) } script.src=`${url}?${arr.join('&')}` document.body.appendChild(script) window[callback] = function(data) { console.log(data) document.removeChild(script) }}
12. JS 获取url参数
function getQueryString(name) { var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i"); var r = window.location.search.substr(1).match(reg); if (r != null) return unescape(r[2]); return null; }// 或export function getQueryStringByStr(data) { const url = data; // 获取url中"?"符后的字串 const theRequest = {}; if (url.indexOf('?') !== -1) { const str = url.substr(1); const strs = str.split('&'); for (let i = 0; i < strs.length; i += 1) { theRequest[strs[i].split('=')[0]] = unescape(strs[i].split('=')[1]); } } return theRequest;}
13. JS发布订阅模式
const event = { clientList: [], listen: function(key , fn) { if (this.clientListen[key]) { this.clientList[key] = [] } this.clientList[key].push(fn) }, trigger: function() { const key = Array.prototype.shift.call(arguments) const fns = this.clientList[key] if (!fns || fns.length === 0 ) { return false } for (let i = 0, fn ;fn = fns[i++];) { fn.apply(this, arguments) } }, remove : function(key , fn) { const fns = this.clientList[key] if (!fns) { return false } if (!fn) { fns && (fns.length = 0) } else { for (let l = fns.length - 1; l>=0; l--) { const _fn = fns[l] if ( _fn ===fn) { fns.splice(l, 1) } } }}const installEvent = (obj) => { for (let i in event) { obj[i] = event[i] }}
VUE常考点
Vue的常见考点,我们公众号里边Vue的面试题已经很多,请移步看吧,也可以把这篇收藏,作为一个中转站。
坎坷的前端面试
Vue常见的考点
vue常见的考点(后续)
前端面试题汇总
快来看看Vue的虚拟DOM和Diff算法的原理
一起来揭开Vue.js的One Piece神秘面纱
有了Vite,还需要Webpack吗?
Vue.js 作者尤雨溪:TypeScript 与 JavaScript 并行才切合实际
React知识
React面试资料,和常见的问题React 开发必须知道的 34 个技巧
官方React入门教程:认识一下React
面试题: 前端框架Vue、angular、React的优点和缺点
30 分钟精通 React 新特性——React Hooks
React面试题必须要会的面试题
React配置代理proxy(实现跨域请求)
Vuex和Redux对比
Vuex 的核心概念:
1. mutation(用于同步操作)
2. action(可用于异步操作,提交 mutation)
3. mutation里面直接修改 state
4. state(单一数据源)
Redux 的核心概念:
1.action (同步action ,或借助 中间件 实现异步操作,action 不会改变 store,只是描述了怎 么改变store)| mutation(用于同步操作)
2.action(可用于异步操作,提交 mutation)
3.reducer(纯函数,根据 action 和旧的 store 计算出新的 store
4.store(单一数据源)
VueX使用原则:
a. 应用层级的状态应该集中到单个 store 对象中。
b. 提交 mutation 是更改状态的唯一方法,并且这个过程是同步的。
c. 异步逻辑都应该封装到 action 里面。
Redux使用原则:
a.单一数据源(一个Redux应用只有一个store),也是单向的数据流;
b.state只读(唯一改变 state 的方法就是触发 action,action 是一个用于描述已发生事件的普通对象。);
c.使用纯函数(reducer)来修改state。
算法
1. 选择排序
function selectionSort(arr) { var len = arr.length; var minIndex, temp; for (var i = 0; i < len - 1; i++) { minIndex = i; for (var j = i + 1; j < len; j++) { if (arr[j] < arr[minIndex]) { //寻找最小的数 minIndex = j; //将最小数的索引保存 } } temp = arr[i]; arr[i] = arr[minIndex]; arr[minIndex] = temp; } return arr;}
2. 二分查找算法
function binarySearch(data,item,start,end){ var end=end || data.length-1; var start=start || 0; var m=Math.floor(start + (end - start) / 2); // 防止查找溢出 if(item === data[m]){ return m; }else if(item<data[m]){ return binarySearch(data,item,start,m-1) //递归调用 }else{ return binarySearch(data,item,m+1,end); } return false;}
3. 快速排序
function quickSort(arr){ if(arr.length==0){ return arr } var pirotIndex=Math.floor(arr.length/2) var pirot = arr.splice(pirotIndex,1)[0] var left=[],right=[] for(var i=0;i if(arr[i]>pirot){ right.push(arr[i]) }else{ left.push(arr[i]) } } return quickSort(left).concat(pirot,quickSort(right))}console.log(quickSort([2,4,6,1,7,8,4,9,99,6])
4. 归并算法
function merge(left, right) { var tmp = []; while (left.length && right.length) { if (left[0] < right[0]) tmp.push(left.shift()); else tmp.push(right.shift()); } return tmp.concat(left, right);}function mergeSort(a) { if (a.length === 1) return a; var mid = ~~(a.length / 2) , left = a.slice(0, mid) , right = a.slice(mid); return merge(mergeSort(left), mergeSort(right));}
5. 回文算法
function palindrome(str) { var newstr = str.replace(/[^0-9a-z]/gi, ""); newstr = newstr.toLowerCase(); for (var i = 0, j = newstr.length - 1; i < j; i++, j--) { if (newstr.charAt(i) !== newstr.charAt(j)) { return false; //逐个字符比较,不匹配返回false } } return true;}
end
本篇至此结束
想了解更多,请关注我们