前端

43 阅读1分钟

var、let和const的区别

  • var没有块级作用域,let和const有块级作用域
    for(var i=0;i<5;i++) {
        console.log(i);
    }
    console.log(i);// 没有块级作用域所以输出12345

    for(let i=0;i<5;i++) {
        console.log(i);// 块级作用域,所以输出1234报错,最外层log不输出
    }
    console.log(i); // let const 声明的只能在花括号之内去使用,超过花括号就报错
  • var 有变量提升 let const 没有变量提升
    console.log(a); // 在我使用a之前提前把变量的声明提到了最上面,
    // 但是只有声明没有负值,所以输出undefined
    var a = 10;

    // (4)var 可以重名  let const 不能重名
    var a = 5;
    var a = 10;
    console.log(a);
  • 暂时性死区:
    1. let/const会被先创建出来,但还未绑定值,所以不能用
    2. 不要再let const声明前使用变量,用了会触发暂时性死区
    a=100;
    let a = 20;
  • var 可以重名,let const 不能重名
    var a = 5;
    var a = 10;
    console.log(a);

flat拍平数组

// 手写flat方法
    const arr = [1,2,[3,4]];
    const res = flat(arr);
    console.log(res);
    // 定义这个函数
    function flat(arr){
        return Array.prototype.concat.apply([],arr)
    }
// 数组里面嵌套一个数组(多维数组拍平)递归
    const arr = [1,2,[3,4,[5,6]]];
    const res = flat(arr);
    console.log(res);
    function flat(arr){
        // 判断arr是不是一维数组
        // some可以把数组当中的每一项都遍历一下(item)就是数组当中的每一项
        const hasDeep = arr.some(item => item instanceof Array) // 判断item是不是一个数组,任何item是一个数组的化,arr都是true
        if(! hasDeep) {
            return arr;
        }
        const res =  Array.prototype.concat.apply([],arr);
        return flat(res); // 递归
    }
    const arr = [1,2,[3,4,[5,6]]];
    const res = flat(arr);
    console.log(res);
    function flat(arr){
        while(arr.some(item => item instanceof Array)){
            arr = Array.prototype.concat.apply([],arr);
        }
        return arr;
    } 

数组去重

    const arr = [10,20,20,30,50,50,60];
    console.log(unique(arr));
    // 新的
    function unique(arr){
        const set = new Set(arr);
        return [...set]
    }
    // 老的
    function unique(arr){
        const res = [];
        arr.forEach(item => {
            if (res.indexOf(item)===-1) { // res里面没有item
                res.push(item);
            }
        });
        return res;
    }

image.png

数组中的最大值

    const arr = [100,5,20,3,200,6];
    console.log(getMax(arr));

    // 第四种方法
    function getMax(arr){
        // 第一次执行reduce的时候n1是100,n2是5,
        // 第二次执行reduce的时候n2是20,n1变成了当前回调函数返回的数字
        return arr.reduce((n1,n2)=>{
            return n1>n2 ? n1:n2 //n1大于n2,把n1返回出去,否则把n2返回出去
        })
    }

    // 第三种方法
    function getMax(arr){
        // n1和n2是相邻的两个数
        arr.sort((n1,n2)=>{
            return n2-n1;
        });
        return arr[0];
    }

    // 两种方法
    // function getMax(arr){
    //     return Math.max(...arr); // 数组打散
    //     // return Math.max.apply(null,arr)
    // }

防抖和节流的区别:

  • 防抖debounce:在事件频繁被触发时,只执行最后一次,input输入
    <body>
        <h1>防抖和节流</h1>
        <input type="text">
        <div></div>
    </body>
    <script>
        const oInp = document.querySelector("input");
        oInp.addEventListener(
            "keyup",
            debounce(function(){
                console.log(oInp.value+"取后台请求");
            })
        )
        function debounce(fn){
            let timer = null;
            return function(){
                if(timer) clearTimeout(timer);
                timer = setTimeout(()=>{
                    fn.call(this.arguments);
                    timer = null;
                },1000)
            }
        }
    </script>

image.png

  • 节流throttle:减少事件执行的次数,有规律地执行,拖拽,scroll
    <h1>节流</h1>
    <div draggable="true"></div>
    // 节流
    const oDiv = document.querySelector("div");
    oDiv.addEventListener("drag",
    throttle(function(e){
        console.log(e.clientX);
    }));
    function throttle(fn){
        let timer = null;
        return function(){
            if(timer) return;
            timer = setTimeout(()=>{
                fn.apply(this,arguments);
                console.log(this,arguments);
                timer = null;
            },100)
        }
    }

image.png