day3_js

本文详细介绍了JavaScript中的高级概念,如数组的reduce方法、Object.fromEntries转换、Rest参数、闭包、var与let/const的区别、newFunction的使用、定时器(setTimeoutsetInterval)、以及防抖和节流的实现。
摘要由CSDN通过智能技术生成

Day3

数组补充:arr.reduce()方法可用于数组求和,第一个参数为一个匿名函数【匿名函数的参数第一个为存储总和的值,第二个为当前遍历内容】,第二个参数为初始值。

对象补充

  1. Object.fromEntries(array)能够将数组转化为对象,但是前提是要以key: value形式

函数

  1. Rest参数(就是 ... )

    有点像我们当时学的解构一样,…也可以接收任意数量的参数

    function sumAll(...args) { // 数组名为 args
      let sum = 0;
      for (let arg of args) sum += arg;
      return sum;
    }
    alert( sumAll(1) ); // 1
    alert( sumAll(1, 2) ); // 3
    alert( sumAll(1, 2, 3) ); // 6
    

    但是Rest参数必须放在函数参数的末尾,否则没有意义

    箭头函数没有this,当然也没有arguments ,arguments很像rest但是其是类数组,没数组的方法

  2. Spread语法

    也为...的语法,作用是 展平

    原因:Spread 语法内部使用了迭代器来收集元素,与 for..of 的方式相同。

    注意:不过 Array.from(obj)[...obj] 存在一个细微的差别:

    • Array.from 适用于类数组对象也适用于可迭代对象。
    • Spread 语法只适用于可迭代对象。

    用于: 1. 复制array和object、替换原先的Object.assign方法

  3. 变量作用域/ 闭包

    对于 ifforwhile 等,在 {...} (代码块)中声明的变量也仅在内部可见:

    闭包:**闭包 是指一个函数可以记住其外部变量并可以访问这些变量。**JavaScript 中的函数会自动通过隐藏的 [[Environment]] 属性记住创建它们的位置,所以它们都可以访问外部变量。

    可以从词法环境进行理解,访问变量是一层一层的沿着词法环境寻找

  4. var和const / let 的区别

    varlet/const 有两个主要的区别:

    1. var 声明的变量没有块级作用域,它们仅在当前函数内可见,或者全局可见(如果变量是在函数外声明的)。
    2. var 变量声明在函数开头就会被处理(脚本启动对应全局变量)【变量提升】。
  5. 全局对象(var,但是不推荐)

    // 将当前用户信息全局化,以允许所有脚本访问它
    window.currentUser = {
      name: "John"
    };
    // 代码中的另一个位置
    alert(currentUser.name);  // John
    // 或者,如果我们有一个名为 "currentUser" 的局部变量
    // 从 window 显式地获取它(这是安全的!)
    alert(window.currentUser.name); // John
    
  6. 函数对象NFE

    function sayHi() {
      alert("Hi");
    
      // 计算调用次数
      sayHi.counter++;
    }
    sayHi.counter = 0; // 初始值
    
    sayHi(); // Hi
    sayHi(); // Hi
    
    alert( `Called ${sayHi.counter} times` ); // Called 2 times
    // 请注意函数对象属性和函数的局部变量不一样
    

    一种新的函数定义方式:

    let sayHi = function func(who) {
      if (who) {
        alert(`Hello, ${who}`);
      } else {
        func("Guest"); // 现在一切正常
      }
    };
    
    let welcome = sayHi;
    sayHi = null;
    
    welcome(); // Hello, Guest(嵌套调用有效)
    

    这种方式主要是针对函数内部嵌套的,这样会防止外部对函数进行更改导致的错误。同时func函数是在函数内部作用域内的不会影响外部作用域,也不会被外部看见

  7. new Function创建函数

    let func = new Function ([arg1, arg2, ...argN], functionBody); 语法格式
    

    使用 new Function 创建的函数,它的 [[Environment]] 指向全局词法环境,而不是函数所在的外部词法环境。因此,我们不能在 new Function 中直接使用外部变量。不过这样是好事,这有助于降低我们代码出错的可能。

  8. 调度(setTimeOut/setInterval)

    setTimeOut是让一个函数在指定时间之后进行执行,setInterval是指定函数在重复的时间间隔一致被调用

    (1) setTimeOut

    function sayHi() {
      alert('Hello');
    }
    setTimeout(sayHi, 1000);
    ------------------
    function sayHi(phrase, who) {
      alert( phrase + ', ' + who );
    }
    setTimeout(sayHi, 1000, "Hello", "John"); // Hello, John
    

    但请注意在此函数中传的被执行的函数是函数的引用,因此不要在后面带括号

    清除定时器的函数为clearTimeOut(id),在这个函数的参数为定时器id

    (2) setInterval

    与settimeout一致,也有clearinterval(id),不同就是这个玩意会重复执行,同时setinterval和settimeout并不会冲突。当这两个使用alert进行弹窗时,即使alert显示了计时器也还在计时。


    (3)settimeout实现setinterval一样的效果【!!!命名内部函数然后就嵌套settimeout,在内部需要命名函数】

    let aa = setTimeout(function ss() {
                alert("hello")
                setTimeout(ss, 1000)
            }, 1000)
    
    // 实际场景:我们要实现一个服务(server),每间隔 5 秒向服务器发送一个数据请求,但如果服务器过载了,那么就要降低请求频率,比如将间隔增加到 10、20、40 秒等。用这个方式比interval好很多
    let delay = 5000;
    
    let timerId = setTimeout(function request() {
      ...发送请求...
    
      if (request failed due to server overload) {
        // 下一次执行的间隔是当前的 2 倍
        delay *= 2;
      }
    
      timerId = setTimeout(request, delay);
    
    }, delay);
    

    (4)嵌套的 setTimeout 相较于 setInterval 能够更精确地设置两次执行之间的延时

    ​ 后者是开始调用与开始调用直接间隔为所设置的时间,这就导致了函数执行时间也会占用所设置的时间,导致间隔时间会小于所设置的时间。但是前者是函数执行完毕以后才会调用,是真正的间隔时间。

    (5)零延时调度 setTimeout(func, 0)(与 setTimeout(func) 相同)用来调度需要尽快执行的调用,但是会在当前脚本执行完成后进行调用。

    // 示例
    function printNumbers(from, to) {
        let current = from;
        let time = setTimeout(function go() {
            alert(current)
            if (current < to) {
                time = setTimeout(go, 1000);
            }
            current++
        }, 1000);
    }
    printNumbers(0, 4)
    
  9. 防抖与节流

    
            function debounce(fn, time) {
                let timer
                return function () {
                    clearTimeout(timer)
                    timer = setTimeout(() => {
                        fn.apply(this, arguments)
                    }, time);
                }
            }
    
    
            function thro(fn, delay) {
                let timer = null
                return function () {
                    if (!timer) {
                        timer = setTimeout(() => {
                            fn.apply(this, arguments)
                            timer = null
                        }, delay);
                    }
                }
            }
    
  1. 防抖与节流

    
            function debounce(fn, time) {
                let timer
                return function () {
                    clearTimeout(timer)
                    timer = setTimeout(() => {
                        fn.apply(this, arguments)
                    }, time);
                }
            }
    
    
            function thro(fn, delay) {
                let timer = null
                return function () {
                    if (!timer) {
                        timer = setTimeout(() => {
                            fn.apply(this, arguments)
                            timer = null
                        }, delay);
                    }
                }
            }
    
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值