js-day10

JS学习之旅-day10

  • [1. 作用域](#1. 作用域)
    • [1.1 局部作用域](#1.1 局部作用域)
    • [1.2 全局作用域](#1.2 全局作用域)
    • [1.3 作用域链](#1.3 作用域链)
    • [1.4 JS垃圾回收机制(GC)](#1.4 JS垃圾回收机制(GC))
    • [1.5 闭包](#1.5 闭包)
    • [1.6 变量提升](#1.6 变量提升)
  • [2. 函数进阶](#2. 函数进阶)
    • [2.1 函数提升](#2.1 函数提升)
    • [2.2 函数参数](#2.2 函数参数)
    • [2.3 箭头函数](#2.3 箭头函数)
  • [3. 解构赋值](#3. 解构赋值)
    • [3.1 数组解构](#3.1 数组解构)
    • [3.2 对象解构](#3.2 对象解构)
  • [4. 数组遍历](#4. 数组遍历)
    • [4.1 forEach](#4.1 forEach)
    • [4.2 filter](#4.2 filter)

1. 作用域

作用域规定了变量能够访问的"范围",分为:局部作用域、全局作用域

1.1 局部作用域

  1. 函数作用域:只能在函数内部访问,外部无法直接访问,函数执行完后,函数内部的变量会被清空。
  2. 块作用域:被 {} 包裹的,使用let、const声明的变量会产生块作用域,var不会产生块作用域

1.2 全局作用域

  1. 写在最外层:

1.3 作用域链

  1. 本质:底层的变量查找机制
  2. 变量查找机制:
    1. 在函数被执行时,会优先在当前函数作用域中查找变量
    2. 如果当前作用域查找不到,则会依次逐级查找父级作用域 直到全局作用域
  3. 总结:
    1. 嵌套关系的作用域串联起来形成了作用域链
    2. 相同作用域中按着从小到大的规则查找变量
    3. 子作用域可以访问父作用域,父作用域无法访问子作用域

1.4 JS垃圾回收机制(GC)

  1. JS中内存的分配和回收都是自动完成的,内存在不使用的时候会被垃圾回收器自动回收。
  2. 内存的生命周期:
    1. 内存分配:当我们声明变量、函数、对象的时候,系统会自动为他们分配内存
    2. 内存使用:即读写内存,也就是使用变量、函数等
    3. 内存回收:使用完毕,由垃圾回收器自动回收不再使用的内存
  3. 说明:
    1. 全局变量一般不会回收(关闭页面回收)
    2. 局部变量不被使用了,会被自动回收掉
  4. 内存泄露:程序中分配的内存由于某种原因程序未释放无法释放叫做内存泄露
  5. 算法说明:
    1. 堆栈空间分配区别:
      1. 栈:由操作系统自动分配释放函数的参数值、局部变量等,基本数据类型都放在栈里
      2. 堆:一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。复杂数据类型放在堆里
    2. 垃圾回收机制两种常见的算法:引用计数法标记清除法
      1. 引用计数(不再使用)

        1. 嵌套引用(循环引用):如果两个对象相互引用,尽管他们不再使用,但垃圾回收器不会进行回收,导致内存泄露

          复制代码
          function fn(){
          	let o1 = {}
          	let 02 = {}
          	o1.a=o2
          	o2.a=o1
          	return '引用计数无法回收'
          }
      2. 标记清除法:从根部扫描对象,能查找到的就是使用的,查找不到的就是要回收的

1.5 闭包

  1. 概念:一个函数对周围状态的引用捆绑在一起,内部函数中访问到其他外层函数的作用域

  2. 闭包 = 内层函数 + 外层函数的变量

    复制代码
    function outer(){
       const a=1
       function f(){
       	console.log(a)
       }
       f()
    }
    outer()
  3. 闭包的作用:封装数据,提供操作,外部也可以访问函数内部的变量

    复制代码
    function outer() {
      const a = 1;
      function fn() {
        console.log(a);
      }
      return fn
    }
    const fn = outer()
    fn()
  4. 风险:内存泄露

1.6 变量提升

  1. 把所有var声明的变量提升到当前作用域前面;let/const 不存在变量提升
  2. 只提升声明,不提升赋值
  3. 变量提升出现在相同作用域中

2. 函数进阶

2.1 函数提升

  1. 会把所有函数声明提升到当前作用域的最前面

  2. 只提升函数声明,不提升函数调用。(函数表达式不存在提升的现象)

    复制代码
    //函数提升
    foo()
    function foo(){	
    	console.log('提升了')
    }
    
    //函数表达式不存在提升
    bar()
    var bar=function(){
    	console.log('报错了')
    }

2.2 函数参数

  1. 动态参数:arguments 是函数内部内置的伪数组变量,它包含了调用函数时传入的所有实参

    复制代码
    function sum() {
      // arguments 动态参数 只存在函数中
      // arguments 是一个伪数组, 它不是一个真正的数组, 但是它有length属性, 可以通过下标访问元素
      // console.log(arguments);
      let total = 0;
      for (let i = 0; i < arguments.length; i++) {
        total += arguments[i];
      }
      console.log(total);
    }
    sum(1, 2);
    sum(1, 2, 3);
    sum(1, 2, 3, 4);
    sum(1, 2, 3, 4, 5);
  2. 剩余参数:允许我们将一个不定数量的参数表示为一个数组

    1. ...是语法符号,之余最末函数形参之前,用于获取多余的实参

    2. 借助...获取的剩余实参,是一个真数组

      function sum(a,...other) {
      console.log(other);
      }
      sum(1, 2); // [2]
      sum(1, 2, 3); // [2,3]
      sum(1, 2, 3, 4); // [2,3,4]
      sum(1, 2, 3, 4, 5); // [2,3,4,5]

  3. 展开运算符 ...

    1. 可以将一个数组展开

      复制代码
      const arr=[1,2,3]
      console.log(...arr) //1 2 3
    2. 说明

      1. 不会修改原数组
      2. 最典型的应用:求数组的最值、合并数组

      const arr = [1, 2, 3, 4, 5];

      console.log(...arr);

      // 求数组最大值
      console.log(Math.max(...arr));

      // 合并数组
      const arr2 = [6, 7, 8, 9, 10];
      const arr3 = [...arr, ...arr2];

2.3 箭头函数

  1. 目的:更简洁的函数写法并且不绑定this,适用于那些需要匿名函数的地方

  2. 基本语法

    复制代码
    // 只有一行代码时, 可以省略大括号,return 会自动返回
    const fn = (a, b) => a + b;
    console.log(fn(1, 2));
    
    // 只有一个形参时, 可以省略小括号
    const fn2 = a => a + 1;
    console.log(fn2(1));
    
    // 直接返回一个对象
    const fn3 = (uname) => ({ uname: uname });
    console.log(fn3("张三"))
  3. 参数

    1. 箭头函数没有arguments参数,但是有剩余参数
    2. 箭头函数不会创建自己的this,它会从自己的作用域链的上一层沿用this

3. 解构赋值

3.1 数组解构

  1. 定义:将数组的单元值快速批量赋值给一系列的变量。

  2. 语法:const [a,b,c] = [100,60,80]

  3. 代码案例:交换变量

    复制代码
    let x = 1;
    let y = 2;
    [x, y] = [y, x];  
    console.log(x, y);

3.2 对象解构

  1. 语法:const { name, age } = { name: 'John', age: 20 };

  2. 注意:变量名和属性名一定要相同

  3. 解构的变量名可以重新命名:const { name: name1, age: age1 } = { name: 'John', age: 20 };

  4. 数组对象解构:

    复制代码
    // 数组对象解构
    const pig = [
      { name: 'John', age: 20 },
    ]
    const [{ name: name2, age: age2 }] = pig;
  5. 多级对象解构

    复制代码
    // 多级对象解构
    const person = {
      uname: 'John',
      uage: 20,
      address: {
        city: 'New York',
    }}
    const { uname, uage, address: { city } } = person;

4. 数组遍历

4.1 forEach

  1. 代码:

    复制代码
    被遍历的数组.forEach(function(当前数组元素,当前元素索引号){
    	//函数体
    })
  2. 注意:

    1. forEach主要是遍历数组
    2. 当前数组元素是必须写的,索引号可以省略
    3. 与map的区别:map有返回,forEach没有

4.2 filter

  1. 筛选数组符合条件的元素,并返回筛选之后元素的新数组

  2. 代码:

    复制代码
    被遍历的数组.filter(function(当前数组元素,当前元素索引号){
    	return 筛选条件
    })
相关推荐
gnip13 分钟前
项目开发流程之技术调用流程
前端·javascript
答案—answer13 分钟前
three.js编辑器2.0版本
javascript·three.js·three.js 编辑器·three.js性能优化·three.js模型编辑·three.js 粒子特效·three.js加载模型
gnip42 分钟前
SSE技术介绍
前端·javascript
yinke小琪1 小时前
JavaScript DOM节点操作(增删改)常用方法
前端·javascript
爱编程的喵1 小时前
从XMLHttpRequest到Fetch:前端异步请求的演进之路
前端·javascript
豆苗学前端1 小时前
手把手实现支持百万级数据量、高可用和可扩展性的穿梭框组件
前端·javascript·面试
yinke小琪1 小时前
JavaScript 事件冒泡与事件捕获
前端·javascript
gzzeason1 小时前
Ajax:现代JS发起http通信的代名词
前端·javascript·ajax
iphone1082 小时前
一次编码,多端运行:HTML5多终端调用
前端·javascript·html·html5
iccb10132 小时前
我是如何实现在线客服系统的极致稳定性与安全性的
前端·javascript·后端