JS必会的面试题4

77 阅读1分钟

for await..of有什么作用

  • for await of用于遍历一组promise
  • promise.all 返回一个数组 并将返回的数据放在一个数组里

知识点

for await..of promise.all

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        function getPromise(num){
            return new Promise((resolve,reject)=>{
                setTimeout(()=>{
                    resolve(num)
                },1000)
            })
        }
        const p1 = getPromise(10);
        const p2 = getPromise(20);
        const p3 = getPromise(30);
        const list = [p1, p2, p3];
        // (async function () {
        //     for await (let res of list) {
        //         console.log(res);
        //     }
        // })();
        for(var i = 0;i<=5;i++){
            console.log(i);
        }
        console.log(i);
        // (async function(){
        //     const data = [10,20,30]
        //     for(let val of data){
        //         const res = await getPromise(val)
        //         console.log(res);
        //     }
        // })()
        // Promise.all返回用于遍历一组promise返回一个数组
        Promise.all(list).then((res)=>{
            console.log(res);
        })
    </script>
</body>

</html>

let const var 有什么区别

  1. 块级作用域
  2. 变量提升
  3. 重名
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        /*
        *------------------------------------------
        *var 没有块级作用域
        *let const 有块级作用域
        *-------------------
        */
    //    for(let i = 0;i<=5;i++){
    //        console.log(i);
    //    }
    //    console.log(i); 报错

    // if(true){
    //     const i = 5
    // }
    // console.log(i); //报错

        /*
        * ----------------------------------
        *var有变量提升
        * let const 没有变量提升
        * 暂时性死区 (temporal dead zone - TDZ)
        * -----------------------------
        */
//    console.log(a);//undefined
//    var a = 10;
//    console.log(b);//暂时性死区
//    let b = 10

        /*
        * ---------------------------
        * var可以重名
        * let const不能重名
        * ------------------------------
        */
    // var a = 5
    // var a = 10
    // console.log(a);

    // var a = 5
    // let a = 10
    // console.log(a);//报错

        /*
        *----------------------------
        * 测试题
        * --------------------------
        */
    // 题目一
    // function fn(){
    //     let a = 10
    //     if(true){
    //         let a = 5
    //     }
    //     console.log(a);
    // }
    // fn()//10
    // 题目二
    // var a = 5
    // if(true){
    //     let a = 10
    // }
    // console.log(a);//5
    // 题目三
    // var a = 5
    // if(true){
    //     let a= 10
    // }
    // console.log(a);//5
    // 题目四
    // function fn(){
    //     console.log(a);
    //     var a = 10
    // }
    // var a=5
    // fn()//undefined


        /*
            产生暂时性死区的原因(es6标准)
            The variables are created when their containing Lexical Environment is instantiated but may not be accessed inany way until the variable’s LexicalBinding is evaluated.
            说人话:let const会先被创建出来 但还未绑定值所有不能用
            好习惯 不要在let const声明前使用变量 用了就触发暂时性死区
        */
    //    a = 100
    //    let a = 10
    //    if(true){
    //        a =100
    //        let a =10
    //    }

    //    function fn(){
    //        a = 100
    //        let a = 10
    //    }
    //    fn()

       for(let i =0;i<3;i++){
           a = 100
           let a = 20
       }
       console.log(a);
    </script>
</body>

</html>

手写flat方法拍平数组

知识点

Array.concat

-Array.concat方法可以连接两个或多个数组

  • Array.concat(1,2,3,[4,5])

Array.some

  • Array.some方法用于遍历数组的每一项
  • Array.some((item)=>item instanceof Array)

判断是不是数组

  • xxx instanceof array

递归

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        let arr = [1,2,3,4,[5,6,[7,8]]]
        
        function flat(arr){
            // some方法 可以遍历数组中的每一项数据
            // 判断数组中的每一项是不是数组
            const deep=arr.some(item => item instanceof Array)
            // 如果不是直接返回
            if(!deep){
                return arr
            }
            // concat方法可以将两个或多个数组连接
            const res = Array.prototype.concat.apply([],arr)
            return flat(res)
        }
        const fn = flat(arr)
        console.log(fn);

        // function flat(arr){
        //     while(arr.some((item) => item instanceof Array)){
        //         arr = Array.prototype.concat.apply([],arr)
        //     }
        //     return arr
        // }
        // const fn = flat(arr)
        // console.log(fn);
        let a = [1,2,3,4,5]
        let b = [40,50,[00,11]]
        let c = [70,80,[00,11]]
        a.concat(b)
        a.concat(c)
        console.log(a);
    </script>
</body>
</html>

数组去重

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        const arr = [10, 20, 20, 30, 50, 50, 60];
        const fn =  unique(arr)
        console.log(fn);
        // function unique(arr){
        //     let res = []
        //     arr.forEach((item)=>{
        //         if(res.indexOf(item) === -1){
        //             res.push(item)
        //         }
        //     })
        //     return res
        // }
        function unique(arr){
            // set类似于数组 set中的每一项数据都是唯一的 用来生成set数据结构
            const set = new Set(arr)
            return [...set]
        }
    </script>
</body>
</html>

求数组中最大值

知识点

  • Array.sort
  • Array.reduce
  • Math.max
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        let arr = [100,5,20,3,200,6]
        console.log(getMax(arr));
        // 第一种方法:Math.max()
        // function getMax(arr){
        //     return Math.max(...arr)
        // }
        // 第二种方法 array.sort()方法
        // function getMax(arr){
        // sort()函数是js内置的一个数组排序函数。默认可以接收一个函数,返回值是比较两个数的相对顺序的值。
        //     arr.sort((n1,n2)=>{
        //         return n2 - n1
        //     })
        //     return arr[0]
        // }
        // 第三种方法 array.reduce方法
        // reduce接收两个参数
        // 参数1 当前回调函数返回的数据
        // 参数2 当前元素
        function getMax(arr){
            return arr.reduce((n1,n2)=>{
                return n1>n2? n1:n2
            })
        }
    </script>
</body>
</html>

手写防抖与节流

知识点

防抖与节流、

标题共同点
防抖在事件频繁时被触发
节流减少事件执行次数
区别应用场景
只执行最后一次input输入
有规律的执行拖拽 scroll
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        div {
            width: 200px;
            height: 200px;
            background-color: #ccc;
        }
    </style>
</head>

<body>
    <input type="text">
    <div draggable="true">

    </div>
    <script>
        //防抖:只执行最后一次 应用场景:input输入
        const inp = document.querySelector("input")
        inp.addEventListener("keyup", debounce(function () {
            console.log(inp.value);
        }))
        function debounce(fn) {
            // 定义一个变量timer
            let timer = null
            // debound内部返回一个函数事件被触发时调用
            return function () {
                // 当事件触发时判断timer是不是空 1.如果不是空就证明函数被又一次调用了 2.清空timer
                if (timer) clearTimeout(timer)
                // 如果是空将一个新的定时器赋值给timer
                timer = setTimeout(() => {
                    // 调用事件中传过来的函数
                    fn.apply(this, arguments)
                    timer = null
                }, 1000)
            }
        }

        // 节流:有规律的执行 应用场景:拖拽 
        const div = document.querySelector("div")
        div.addEventListener("drag",
            throttle(function (e) {
                console.log(e.clientX);
            }))
        console.log(div);
        function throttle(fn) {
            // 定义一个变量timer
            let timer = null
            // 内部返回一个函数当事件被触发时调用
            return function () {
                // 判断timer是不是空 1、如果不是证明函数正在被调用 2、直接return出去
                if (timer) return
                timer = setTimeout(() => {
                    // 调用事件中传过来的函数
                    fn.apply(this, arguments)
                    timer = null
                }, 1000);
            }
        }
    </script>
</body>

</html>