前言

     在我们平常面试中,手写题是必不可少的一项环节,在本篇文章中,将会教大家手把手教会大家手写一部分手写题,希望对大家有所帮助.

正文

1.手写防抖节流

     在JavaScript中,防抖(Debounce)和节流(throttle)是两种常用的优化高频触发事件的策略,它们通常用于窗口大小,滚动,出入导航等场景,以减少事件处理函数的执行频率,提高性能

什么是防抖?

防抖是指当我们触发一个事件时,在n秒内如果又被触发,就会重新计算执行时间。就比如。一个一个按钮button,我们给它添加一个防抖。设置3秒内,执行完毕,如果在这3秒内,又被重新点击,就会重新计算3秒。下面是一份测试代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <button id="btn">点击</button>

    <script>
        const btn = document.getElementById('btn');
        btn.addEventListener('click',debouce(handle,3000))

        function handle(){
            console.log('点击了');
        }

        function debouce(fn,wait){
            let timer = null;
            return function(...args){
                if(timer) clearTimeout(timer);
                timer = setTimeout(() => {
                    fn.call(this, args);
                }, wait);
            }
        }
    </script>
</body>
</html>

我们看到函数debouce()这就是实现防抖的核心所在。我们现在来剖析一下代码。
在写手写防抖节流的过程中,其实也是一种考验我们闭包掌握的如何了,什么?不知道闭包是什么玩意。这里我们简单陈述一下闭包的概念,在js中根据词法作用域的规则,内部函数可以访问外部函数的变量。当内部函数被拿到外部调用时,即使外部函数已经执行完毕,内部函数对外部函数的变量访问依旧存在引用,那这些被引用的变量就会以一个集合的形式保存在内存中,这种集合就是闭包。这一点大家可以稍后自己恶补一下闭包的知识点,毕竟真的很重要。 在代码中,我们对按钮btn进行事件监听,当按钮被点击就会打印一句话。但是为了防止一直点一直触发,我们就给它使用防抖处理。防抖函数debouce()接收两个参数,一个是需要防抖处理的函数,一个是定时器触发的时间。let timer = null我们创建一个用于判断是否存在定时器的变量。返回一个匿名函数。使用展开运算符...args表示接收debouce()返回给内部函数的所有参数。进入到匿名函数中,if()用于判断在此之前定时器timer是否存在,如果存在就清除这个定时器,并重新创建一个定时器。这也就是说在js中防抖是指在n秒内,函数又被触发,就重新计时。在定时器中我们使用显示绑定,将fnthis绑定在匿名函数的上下文对象上。手写一个防抖函数,需要牢记它的处理理念就好了在n秒内,事件在又被触发,计时器会重新计时

在面试中的常见的JavaScript手写代码题之小白新手教程(一)_数组

什么是节流?

其实节流的思路跟节流差不多的,唯一不同的就是判断的变量不同。在防抖中,我们判断的是否存在定时器,存在就重新计时,而节流使用的也是一个中间变量inThrottle,当我们第一次点击按钮时,inThrottle的值为false表示还未开启节流,这时给inThrottle赋值为true就表示开启节流,后面只有等待n秒后,点击才会生效。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <button id="btn">点击</button>
    <script>
        const btn = document.getElementById('btn')

        btn.addEventListener('click',throttle(handle,1000))

        function handle(){
            console.log('click');
        }

        function throttle(fn,limit){
            let inThrottle;
            return function(...args){
                if(!inThrottle){
                    fn.apply(this, args);
                    inThrottle = true;
                    setTimeout(()=>{
                        inThrottle = false;
                        return inThrottle
                    },limit);
                }
            }
        }
    </script>
</body>
</html>

在面试中的常见的JavaScript手写代码题之小白新手教程(一)_运算符_02

2.手写扁平化数组

使用递归思想

扁平化数组是指什么呢?扁平化数组的意义是将一个多维数组变成一维数组。这里我们使用递归的思想解决,因为多维数组就是在一维数组中嵌套数组,然后在其内部也嵌套了数组。借助这一点,我们可以判断一维数组中的第i个元素是否是一个数组,如果是就递归调用,否则直接把该元素存在临时数组中。最后执行完,就返回这个临时数组

function flattenArray(arr){
    let result = []
    for(let i = 0; i < arr.length; i++){
        if(Array.isArray(arr[i])){
            result = result.concat(flattenArray(arr[i]));
        }else{
            result.push(arr[i]);
        }
    }
    return result;
}

let arr = [1,[2,[3,4,[5,6]]]]
console.log(flattenArray(arr));

在面试中的常见的JavaScript手写代码题之小白新手教程(一)_html_03

在面试中的常见的JavaScript手写代码题之小白新手教程(一)_运算符_04

使用flat()函数一键扁平

在ES10中,推出了一个flat()的方法,使用方法非常的简单

let arr = [1,[2,[3,4,[5,6]]]]
console.log(arr.flat(Infinity));

flat()中接收一个参数,可以表示扁平化到几维数组,使用Infinity这个极小值,就会变成一维数组。

3.Js中数组去重

使用set 去重

在js中set本身就是不允许存在相同的数据,凭借这一点我们可以很好的进行数组去重

function uniqueArray(arr){
    return [...new Set(arr)]
}
let arr = [1,2,3,4,5,8,8,9,9]

const newArr = uniqueArray(arr)
console.log(newArr);

在函数uniqueArray()中我们返回一个数组,但是这里会将我们传入的数组arr进行一个去重的操作,这里我们使用展开运算符,将对象中的值全部拿出来给到数组。如果我们不使用展开运算符,我们看看得到的是什么

在面试中的常见的JavaScript手写代码题之小白新手教程(一)_运算符_05

不使用展开运算符,在数组就会存一个set对象,所以这里使用展开运算符就是将对象中的元素放在数组中。

在面试中的常见的JavaScript手写代码题之小白新手教程(一)_运算符_06

使用过滤器filter

function uniqueArray(arr){
    return arr.filter((item,index)=>arr.indexOf(item) === index)
}
let arr = [1,2,3,4,5,6,7,7,8,8]
let newArray = uniqueArray(arr)
console.log(newArray);

这里过滤器filter()可以帮助我们去除我们不想要的元素,这里我们通过下标去判断。因为IndexOf()会返回第一个这个元素的下标,如果与当前下标不符,就表示重复(图画的有点low,请大家见谅)

在面试中的常见的JavaScript手写代码题之小白新手教程(一)_运算符_07

如图所示第一第二个元素都为'1',但是第二个元素的下标为1而不是IndexOf()返回的下标'0',所以这个元素就会被过滤.