第 1 题:(滴滴、饿了么)写 React / Vue 项目时为什么要在列表组件中写 key,其作用是什么?
1.更准确
key保证不是就地复用,在sameNode函数中避免就地复用的情况,所以更加准确。
2.更加快
利用key的唯一生成性map对象来获取关键节点,比遍历方式更快,提升diff效率。Vue的diff算法中,如果交叉对比没有结果,会根据map映射找到数组中的key,如果没有设置,会遍历查找,速度没有map映射快。
第 2 题:[‘1’, ‘2’, ‘3’].map(parseInt)?
Array.map()里面接收一个callback回调函数作为参数,callback()回调函数参数(item,index,arr)数组项,数组值,数组本身。
当传入parseInt的时候,parseInt(‘1’,0),radix为0,取值为1;
parseInt(‘2’,1),取值为NaN,parseInt(‘3’,2),基数是2,取值为NaN;
第 3 题:(挖财)什么是防抖和节流?有什么区别?如何实现?
防抖:
触发高频事件后N秒内函数只会执行一次,如果N秒内高频事件再次触发,则重新计算时间。
取消之前的延时调用方法。
/* 防抖 */
function dou(fn, wait) {
var time = null;
return function () {
clearTimeout(time)
// time = setTimeout(function () {
// console.log(this)//window
// fn.apply(this, arguments)//这样的话 this为window和直接 fn()调用是一样的效果,因为他们的this都是window
// }, wait);
time = setTimeout(() => {
// console.log(this)//div
fn.apply(this, arguments)//确保dou函数的this(上下文还是div)
}, wait);
}
}
function demo() {
console.log('防抖啦')
}
// 用句柄事件绑定调用dou事件,所以this为div节点对象
document.querySelector('div').addEventListener('scroll', dou(demo, 1000))
节流:
高频事件触发,但秒内只函数值执行一次,所以节流会稀释函数的执行次数。
每次触发事件都判断是否有等待执行的延时函数
/* 节流 */
// 节流函数
function throttle(fun, wait) {
let previous = 0;
return function() {
let now = +new Date();
// 判断函数的时间是否小于定值
if (now - previous > wait) {
fun.apply(this, arguments);
previous = now;
}
}
}
function demo() {
console.log('节流了');
}
document.querySelector('div').addEventListener('click', throttle(demo, 1000));
第 4 题:介绍下深度优先遍历和广度优先遍历,如何实现?
深度优先遍历(Depth-First-Search)
是搜索算法的一种,它沿着树的深度遍历树的节点,尽可能深地搜索树的分支。过程一直进行到已探寻源节点到其他所有节点为止,如果还有未被发现的节点,则选择其中一个未被发现的节点为源节点并重复以上操作,直到所有节点都被探寻完成。
广度优先遍历(Breadth-First-Search)
是从根节点开始,沿着图的宽度遍历节点,如果所有节点均被访问过,则算法终止,BFS 同样属于盲目搜索,一般用队列数据结构来辅助实现BFS
第 5 题:ES5/ES6 的继承除了写法以外还有什么区别?
ES5的继承
function a() {
this.name = 'a';
}
a.prototype.getName = function getName() {
return this.name
}
function b() {}
b.prototype = new a();
console.log(b.prototype.__proto__ === a.prototype); // true
console.log(b.__proto__ === a); // false
console.log(b.__proto__); // [Function]
ES6的继承
```javascript
```javascript
```javascript
class A {
constructor(a) {
this.name = a;
}
getName() {
return this.name;
}
}
class B extends A{
constructor() {
super();
}
}
console.log(B.prototype.__proto__ === A.prototype); // true
console.log(B.__proto__ === A); // true
console.log(B.__proto__); // [Function: A]