前端面试题

1.写 React / Vue 项目时为什么要在列表组件中写 key,其作用是什么?

我的理解,没有key的时候节点会复用,有key的时候节点不会复用,

1. 更准确,带key不会就地复用

2. 更快,利用key的唯一性生成map对象来获取对应节点,比遍历方式更快。

第 4 题:介绍下 Set、Map、WeakSet 和 WeakMap 的区别?

WeakSet和Set都是构造函数,可以使用new命令创建相应的数据结构,并且值都是唯一的;
WeakSet 与 Set 的区别:
1、WeakSet 的成员只能是对象,而不能是其他类型的值,而 Set 对象的成员可以是任意类型的值;
2、WeakSet 对象中储存的对象值都是被弱引用的,即垃圾回收机制不考虑 WeakSet 对该对象的应用,如果没有其他的变量或属性引用这个对象值,则这个对象将会被垃圾回收掉(不考虑该对象还存在于 WeakSet 中),所以,WeakSet 对象里有多少个成员元素,取决于垃圾回收机制有没有运行,运行前后成员个数可能不一致,遍历结束之后,有的成员可能取不到了(被垃圾回收了);
3、由于以上第二点的原因,es6规定WeakSet不能够被遍历,无法使用keys,values等遍历方法,并且不存在size属性。

Map和WeakMap都是构造函数,用域生成键值对的集合;
Map和WeakMap的区别:
1、WeakMap只接受对象作为键名,不接受其他类型的值作为键名,而Map可以接受任何类型的值作为键名;
2、WeakMap的键名所引用的对象都是弱引用,所以这个对象的其他引用都被清除,垃圾回收机制就会释放这个对象所占用的内存;
3、由于第二点的原因,WeakMap不存在遍历操作,没有size的属性,因为WeakMap的键名是不可预测的,可能在不知道的时间,作为键名的对象就被垃圾回收机制清除;
4、不支持clear方法。

第 5 题:介绍下深度优先遍历和广度优先遍历,如何实现?

深度遍历


function dfc(root){
    if(root==null)
        return [];
    var result = [];//存放遍历结果的数组
    var nodeStack = [];//暂存元素的栈
    nodeStack.push(root);
    while(nodeStack.length>0){
        let n = nodeStack.pop();
        result.push(n);
        let children = n.children;
        //要从左到右遍历,所以要反向进栈
        for(let i=children.length-1;i>=0;i--){
            nodeStack.push(children[i]);
            }
        }
    return result;
}
 
dfc(document.body);

广度优先遍历

function bfc(root){
    if(root==null)
        return [];
    var result = [];//存放遍历结果的数组
    var nodeQueue = [];//暂存元素的队列
    nodeQueue .push(root);
    while(nodeQueue.length>0){
        let n = nodeQueue.shift();
        result.push(n);
        let children = n.children;
        for(let i=0;i<children.length;i++){
            nodeQueue.push(children[i]);
        }
    }
    return result;
}
 
bfc(document.body);

第 7 期:ES5/ES6 的继承除了写法以外还有什么区别?

  1. class不会函数提升。Foo 进入暂时性死区,类似于 letconst 声明变量。
  2. class 声明内部会启用严格模式。
  3. // 引用一个未声明的变量
    function Bar() {
      baz = 42; // it's ok
    }
    const bar = new Bar();
    
    class Foo {
      constructor() {
        fol = 42; // ReferenceError: fol is not defined
      }
    }
    const foo = new Foo();

  4. class 的所有方法(包括静态方法和实例方法)都是不可枚举的。
  5. class 的所有方法(包括静态方法和实例方法)都没有原型对象 prototype,所以也没有[[construct]],不能使用 new 来调用。
  6. 必须使用 new 调用 class

第 11 题:将数组扁平化并去除其中重复数据,最终得到一个升序且不重复的数组 

Array.from(new Set(arr.flat(Infinity))).sort((a,b)=>{ return a-b})

Array.from()方法就是将一个类数组对象或者可遍历对象转换成一个真正的数组。

使用 Infinity 作为深度,展开任意深度的嵌套数组

arr3.flat(Infinity);

第 30 题:请把俩个数组 [A1, A2, B1, B2, C1, C2, D1, D2] 和 [A, B, C, D],合并为 [A1, A2, A, B1, B2, B, C1, C2, C, D1, D2, D]。

let arrA = ["A1", "A2", "B1", "B2", "C1", "C2", "D1", "D2"];
let arrB = ["A", "B", "C", "D"];
arrC = arrA
  .map((item) => {
    if (item == arrB[0] + 2) {
      return [item, arrB.shift()];
    } else {
      return item;
    }
  })
  .flat();
console.log(arrC);

第 31 题:改造下面的代码,使之输出0 - 9,写出你能想到的所有解法。 

for (var i = 0; i< 10; i++){
	setTimeout(() => {
		console.log(i);
    }, 1000)
}
// 解法一:
for (let i = 0; i< 10; i++){
  setTimeout(() => {
    console.log(i);
  }, 1000)
}
//解法二,利用 setTimeout 函数的第三个参数,会作为回调函数的第一个参数传入
for (var i = 0; i < 10; i++) {
    setTimeout(i => {
      console.log(i);
    }, 1000, i)
  }

使用迭代的方式实现 flatten 函数 #54

var arr = [1, [2, 3, [4]]];

function faltten() {
  while (arr.some((item) => Array.isArray(item))) {
    arr = [].concat.apply([], arr);
  }
}
faltten(arr);
console.log(arr);

第 38 题:下面代码中 a 在什么情况下会打印 1?

var a = ?;
if(a == 1 && a == 2 && a == 3){
 	conso.log(1);
}
var a = {
  i: 1,
  toString() {
    return a.i++;
  }
}

if( a == 1 && a == 2 && a == 3 ) {
  console.log(1);
}

 


[] == ![]; // true [] == false --> [] == 0 --> "" == 0 --> 0 == 0
2 == [2]; // true  2 == "2" --> 2 == 2
"" == [null]; // true  "" == ""  (ps: String([null]) === "";  String(null) === "null")
"0" == false; // true "0" == 0 --> 0 == 0
false == 0; // true 0 == 0
false == ""; // true 0 == "" --> 0 == 0
false == []; // true 0 == [] --> 0 == "" --> 0 == 0
"" == 0; // true 0 == 0
"" == []; // true "" == ""
0 == []; // true 0 == "" --> 0 == 0

空字符串转换成boolen为false,只要字符串有长度,就转换成ture,

对象通过tostring转换成字符串,通过valueof转换成数字,一个对象同时存在valueof和tostring方法,valueof会被优先调用

第 46 题:输出以下代码执行的结果并解释为什么

var obj = {
    '2': 3,
    '3': 4,
    'length': 2,
    'splice': Array.prototype.splice,
    'push': Array.prototype.push
}
obj.push(1)
obj.push(2)
console.log(obj)

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王源偷我华子抽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值