zoukankan      html  css  js  c++  java
  • 2020高级前端面试题(学习笔记)

    2020高级前端面试题(学习笔记)

    参考文章:https://www.cnblogs.com/sexintercourse/p/12418512.html

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

    1. 更准确。因为带key就不是就地复用了

    2. 更快。利用key的唯一性生成map对象来获取对应节点,比遍历方式更快。主要是为了提升diff【同级比较】的效率。自己想一下自己要实现前后列表的diff,如果对列表的每一项增加一个key,即唯一索引,那就可以很清楚的知道两个列表谁少了谁没变。而如果不加key的话,就只能一个个对比了,

    vue和react都是采用diff算法来对比新旧虚拟节点,从而更新节点。在vue的diff函数中(建议先了解一下diff算法过程)。在交叉对比中,当新节点跟旧节点头尾交叉对比没有结果时,会根据新节点的key去对比纠结点数组中的key,从而找到相应旧节点(这里对应的是一个key => index的 map映射)。如果没找到就认为是一个新增节点。而如果没有key,那么就会采用遍历查找的方式去找到对应的旧节点。一种是一个map映射,另一种是遍历查找。相比而言,map映射的速度更快。

    二、['1', '2', '3'].map(parseInt) what & why?

    首先让我们回顾一下,map函数的第一个参数callback

    var new_array = arr.map(function(currentValue[, index[, array]])) {
        // Return element for new_array
    }[, thisArg]

    这个callback一共可以接收三个参数,其中第一个参数代表当前被处理的元素,而第二个参数代表该元素的索引。

    而parseInt则是用来解析字符串的,使字符串成为指定基数的整数

    parseInt(string, radix)

    parseInt接收2个参数,第一个表示被处理的值(字符串),第二个表示为解析时的基数

    了解这两个函数后,我们可以模拟一下运行情况

    parseInt('1', 0)

    radix为0时,且string参数不以“0x”或“0”开头时,按照10为基数处理。此时返回1

    parseInt('2', 1)

    radix为1,1进制表示的数中,最大值应小于2,所以无法解析,返回NaN

    parseInt('3', 2)

    radix为2,2进制表示的数中,最大值小于3,所以无法解析,返回NaN

    map函数返回的是一个数组,所以最后结果为[1, NaN, NaN]

    三、什么是防抖和节流?有什么区别?如何实现?

    1. 防抖

    触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间。

    思路:

    每次触发事件时都取消之前的延时调用方法

    function debounce(fn) {
        let timeout = null; // 创建一个标记用来存放定时器的返回值
        return function () {
            clearTimeout(timeout); // 每当用户输入时把前一个setTimeout clear掉
            timeout = setTimeout(() => { // 然后又创建一个新的setTimeout, 这样就能保证输入字符后的interval间隔内如果还有字符输入的话,就不会执行fn函数
                fn.apply(this, arguments);
            }, 500);
        };
    }
    
    function sayHi () {
        console.log('防抖成功');
    }
    
    var inp = document.getElementById('inp');
    inp.addEventListener('input', debounce(sayHi)); // 防抖

    2. 节流

    高频事件触发,但在n秒内只会执行一次,所以节流会稀释函数的执行频率。

    思路

    每次触发事件时都判断当前是否有等待执行的延时函数。

    function throttle (fn) {
        let canRun = true; // 通过闭包保存一个标记
        return function () {
            if (!canRun) return; // 在函数开头判断标记是否为true,不为true则return;
            canRun = false;
            setTimeout(() => {
                fn.apply(this, arguments);
                canRun = true;
            }, 500);
        }
    }
    
    window.addEventListener('resize', throttle(sayHi));
  • 相关阅读:
    Educational Codeforces Round 88 (Rated for Div. 2) D. Yet Another Yet Another Task(枚举/最大连续子序列)
    Educational Codeforces Round 88 (Rated for Div. 2) A. Berland Poker(数学)
    Educational Codeforces Round 88 (Rated for Div. 2) E. Modular Stability(数论)
    Educational Codeforces Round 88 (Rated for Div. 2) C. Mixing Water(数学/二分)
    Codeforces Round #644 (Div. 3)
    Educational Codeforces Round 76 (Rated for Div. 2)
    Educational Codeforces Round 77 (Rated for Div. 2)
    Educational Codeforces Round 87 (Rated for Div. 2)
    AtCoder Beginner Contest 168
    Codeforces Round #643 (Div. 2)
  • 原文地址:https://www.cnblogs.com/cathy1024/p/13618332.html
Copyright © 2011-2022 走看看