【interview】2020.07.07 First One
函数防抖是间隔超过一定时间后才会执行
函数节流是一定时间段内只执行一次
【1 月最新】前端 100 问:能搞懂 80% 的请把简历给我
前端面试考点多?看这些文章就够了(2019年6月更新版)
1. 打印值
例如: console.log(1); // 1 题: console.log({} === {}); // console.log(NaN === NaN); // console.log([] === false); // console.log(![] == false); // console.log(typeof null); // console.log(typeof []); // console.log([] instanceof Object); // console.log(/a/ === /a/); // console.log(1 === new String('1')); //
2. 打印值
3. 数组的方法及其作用 (更多详见:https://es6.ruanyifeng.com/#docs/array#Array-from)
- 遍历处理
Array.prototype.forEach(); // 遍历数组,处理逻辑
- 返回新数组
Array.prototype.map(); // 遍历数组,返回新数组
Array.prototype.filter(); // 遍历数组,返回符合条件为 true 的元素组成新数组
Array.prototype.reduce(); // 也可以根据老数组,可以不返回数组,比如 返回 一个新的字符串
-
- 返回 true/false
Array.prototype.some(); // 遍历数组,有一个满足条件为 true, 则返回 true
Array.prototype.every(); // 遍历数组,每个元素都满足条件为 true,才返回 true
- 查找数组中满足条件的元素,找不到返回 false,找到了则返回该元素
Array.prototype.find(); // 只会找到第一个符合的,找到之后就会直接返回,就算下面还有符合要求的,也不会再找下去
4. 将数组扁平化去并除其中重复部分数据,最终得到一个升序且不重复的数组
最佳:
-
let sortOneFlat = (arr) => { return Array.from(new Set(arr.flat(Infinity))).sort((a,b)=>{ return a-b}) } sortOneFlat([5, 5, 1, 2, 5, 1, 2, 415, 1, 2, 15, 15, [5, 5, 555, 654, 541616, 2132, 213136541, [1, 545, 15, 1, 151, 3131354]]]);
[1, 2, 5, 15, 151, 415, 545, 555, 654, 2132, 541616, 3131354, 213136541]
-
function flatArr(arr) { ...... } var arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10]; flatArr(arr);
- 答案
-
// 将数组扁平化去并除其中重复部分数据,最终得到一个升序且不重复的数组 let flatArr = (arr) => { let newArr = []; for (let i = 0; i < arr.length; i++) { if (arr[i] instanceof Array) { flatArr(arr[i]).forEach(item => { newArr.indexOf(item) === -1 && (newArr = [...newArr, item]); }); } else { newArr.indexOf(arr[i]) === -1 && (newArr = [...newArr, arr[i]]); } } return newArr.sort((a, b) => a - b); }; var arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10]; console.log(flatArr(arr));
4.2 输入年月日的字符串,获取到年龄
- 答案
-
/** * 获取年龄 * @param birthday * @return number */ let getAge = (birthday) => { // 前置校验 // string // YYYY-MM-DD /\d{4}-\d{2}-\d{2}/ // 非法时间 1999-20-33 const [birYear, birMonth, birDay] = birthday.split('-').map(i => +i); const cur = new Date(); const curYear = cur.getFullYear(); const curMonth = cur.getMonth() + 1; const curDay = cur.getDate(); const yearDiff = curYear - birYear; if (curMonth > birMonth) { return yearDiff; } else if (curMonth < birMonth) { return yearDiff - 1; } else if (curDay > birDay) { return yearDiff } return yearDiff - 1; // ((curMonth === birMonth && birDay > curDay) // || (curMonth > birMonth)) // && (yearDiff -= 1); // // return yearDiff; }; // getAge('2019-06-08'); getAge('2019-07-07'); // getAge('2019-07-06');
考点: 函数优化,函数描述头、入参校验、命名规范
以下是复习网上搜的题目
参考: https://www.cnblogs.com/feiyuhuo/p/5571147.html
5. 一次完整的HTTP事务是怎样的一个过程?
基本流程:
a. 域名解析
b. 发起TCP的3次握手
c. 建立TCP连接后发起http请求
d. 服务器端响应http请求,浏览器得到html代码
e. 浏览器解析html代码,并请求html代码中的资源
f. 浏览器对页面进行渲染呈现给用户
6. 什么是函数节流,有什么作用?请写一段函数节流的示范代码
参考:https://www.cnblogs.com/tianxiaxuange/p/10220695.html
7. JS基础数据类型与引用数据类型分别有哪些?请编写 getType 函数代码,返回变量的具体类型名称。
js 基础数据类型:null、undefined、number、boolean、string、symbol
js 引用数据类型:object、function
-
/** * 返回变量的具体类型名称 * @param obj 待判断的变量 */ function getType(obj){ var typeName = Object.prototype.toString.call(obj); if( typeName == "[object Object]"){ return typeName = obj.constructor.name; }else{ return typeName.slice(8,-1); } } getType(1); // Number // getType('1'); // String // getType(['1']); // Array // getType({a: ['1']}); // Object // getType(null); // Null // getType(window.lllklk); // Undefined // getType(true); // Boolean
8. 数组去重:
-
/** * 数组去重 * @param arr 老数组 * @return newArr 新数组 */ function singleArr(arr) { return (arr instanceof Array) ? arr.filter((item, index) => arr.indexOf(item) === index) : []; } singleArr([111, 2, 42, 32, 2, 422, 3, 3, 1, 2, 1, 313]); // [111, 2, 42, 32, 422, 3, 1, 313]
以下方式更好:
-
/** * 数组去重 * @param arr 老数组 * @return newArr 新数组 */ function singleArr(arr) { return Array.from(new Set([...arr])); } singleArr([111, 2, 42, 32, 2, 422, 3, 3, 1, 2, 1, 313]); // [111, 2, 42, 32, 422, 3, 1, 313]
9. 同步和异步的区别
- 同步
就是上一件事情没有完成,继续处理上一件事情
只有上一件事情完成了,才会做下一件事情。
JS中大部分都是同步编程。
- 异步
规划要做一件事情,但是不是当前立马去执行这件事情,需要等一定的时间
这样的话,我们不会等着他执行,而是继续执行下面的操作
只有当下面的事情都处理完成了,才会返回头处理之前的事情
如果下面的事情并没有处理完成,不管之前的事情有没有到时间,都需要等待。
在JS中,异步编程只有四种情况:
- 定时器都是异步编程的
- 所有的事件绑定都是异步编程的
- Ajax读取数据都是异步编程的,我们一般设置为异步编程
- 回调函数都是异步编程的
10. 若想真正意义上的深拷贝,请递归
-
/** * 递归的方式 深拷贝对象 * @param obj 老对象 * @return result 新对象 */ function deepCopy(obj) { var result = Array.isArray(obj) ? [] : {}; for (var key in obj) { if (obj.hasOwnProperty(key)) { if (typeof obj[key] === 'object' && obj[key]!==null) { result[key] = deepCopy(obj[key]); //递归复制 } else { result[key] = obj[key]; } } } return result; } /****************************************/ var syb = Symbol('obj'); var person = { name :'tino', say: function(){ console.log('hi'); }, ok: syb, un: undefined } deepCopy(person);
注意:
- 赋值运算符 = 实现的是浅拷贝,只拷贝对象的引用值
- JavaScript 中数组(concat、slice)和对象(assign、展开运算符… 、)自带的拷贝方法都是“首层浅拷贝”;
- JSON.stringify 实现的是深拷贝,但是对目标对象有要求(非 undefined,function,symbol。当值为undefined、function、symbol 会在转换过程中被忽略。。。)
-
var syb = Symbol('obj'); var person = { name :'tino', say: function(){ console.log('hi'); }, ok: syb, un: undefined } var copy = JSON.parse(JSON.stringify(person)) // copy // {name: "tino"}
参考https://blog.csdn.net/caroline323123/article/details/100735817