JavaScript 笔记 --- part6 --- JS进阶 (part1)

JS 进阶(part1)

作用域

局部作用域

  • 定义: 局部作用域指的是在函数内部定义的变量,只能在函数内部访问,外部不能访问。

  • 特点: 局部作用域变量只能在函数内部或代码块中访问,外部不能访问。

  • 分类:

    • 函数作用域: 指的是在函数内部定义的变量,只能在函数内部访问,外部不能访问。

    • 块作用域: 指的是在代码块({})中定义的变量,可以在代码块中访问,外部不能访问。

全局作用域

  • 定义: 全局作用域指的是在函数外部定义的变量,可以在整个程序范围内访问。

  • 特点: 全局作用域变量可以在整个程序范围内访问。

  • 建议: 不建议在全局作用域定义变量,容易造成命名冲突。

作用域链

  • 定义: 作用域链是由一系列变量对象组成的链式结构,它决定了变量的查找方式。

  • 作用: 作用域链的作用是保证对变量的访问权限。

  • 机制: 当解释器在执行代码时,会在当前作用域和上层作用域中查找变量,如果在当前作用域中没有找到,则继续在上层作用域中查找,直到找到为止。

  • 特点: 子作用域能够访问父作用域, 但父作用域不能访问子作用域。

JS 垃圾回收机制

  • 定义: 垃圾回收机制是指自动释放不再使用的内存,以便为应用程序提供更多的内存空间。

  • 内存的生命周期:

    1. 分配: 当我们声明变量、函数或创建对象时,系统会在内存中分配一块内存空间。
    2. 使用: 程序运行时(读写内存),系统使用分配的内存空间。
    3. 释放: 程序运行结束时,系统释放分配的内存空间。
  • 注意:

    1. 全局变量: 全局变量的生命周期与程序运行时长相关,当程序结束时,系统会自动释放全局变量所占用的内存。
    2. 局部变量: 局部变量的生命周期与函数执行时长相关,当函数执行结束时,系统会自动释放局部变量所占用的内存。
    3. 内存泄露: 未释放或无法释放内存。
  • 算法说明:

    1. 标记清除: 定义"无法到达的对象", 从根部出发, 如果能找到标记对象, 暂时不清除, 找不到则清除。
    2. 引用计数: 定义"内存不再使用", 就是看一个对象是否有指向它的引用, 如果没有, 则说明该对象不再使用, 可以进行回收。 / 缺点: 嵌套引用时, 无法回收。

闭包

  • 定义: 闭包是指有权访问另一个函数作用域的函数,创建闭包的常见方式是函数嵌套。

  • 特点: 闭包 = 内层函数 + 外层函数的变量

  • 作用: 封闭数据, 提供操作, 外部也可以访问函数内部的变量

  • 优点:

    1. 可以读取函数内部的变量和参数
    2. 可以在函数外部修改变量的值
    3. 延迟初始化, 只有在调用函数时才初始化变量
  • 缺点:

    1. 内存泄漏, 闭包会占用内存, 导致内存泄漏
    2. 性能问题, 每次调用函数都会创建新的闭包, 性能较低
javascript 复制代码
function outer() {
  let a = 1;
  function inner() {
    console.log(a);
  }
  return inner;
}

cosnt fun = outer();
fun();

变量提升

  • 定义: 变量提升是指 JavaScript 在执行代码前,会将在当前作用域下, var 声明的变量和函数, 提升到当前作用域的最前面, 只提升声明, 不提升赋值。

  • 作用: 变量提升可以让变量在函数内部使用前就已经声明, 避免报错, 但实际开发中, 应该避免使用变量提升。

展开运算符

  • 定义: 展开运算符是指将数组或类数组对象转换为用逗号分隔的参数序列。

  • 作用: 展开运算符可以将数组或类数组对象转换为用逗号分隔的参数序列, 方便求最值和合并数组。

  • 语法: 展开运算符是三个点(...)

  • 注意: 展开运算符只能用于数组或类数组对象, 不能用于字符串, 对象, Map, Set 等。

javascript 复制代码
let arr = [1, 2, 3];
let arr2 = [4, 5, 6];

let newArr = [...arr, ...arr2]; // [1, 2, 3, 4, 5, 6]

let max = Math.max(...newArr); // 6

函数

函数提升

  • 定义: 函数提升是指 JavaScript 在执行代码前,会将在当前作用域下, 函数声明的函数, 提升到当前作用域的最前面。

函数参数

  • 动态参数

    • 定义: 动态参数指的是函数调用时, 传入的参数个数不确定, 可以是 0 个或多个。

    • 用法: 使用 arguments 对象(伪数组), 可以获取调用函数时传入的参数。

    • 作用: 可以实现函数的可变参数。

    javascript 复制代码
    function getSum() {
      let sum = 0;
      for (let i = 0; i < arguments.length; i++) {
        sum += arguments[i];
      }
      return sum;
    }
    
    let result = getSum(1, 2, 3); // 6
  • 剩余参数

    • 定义: 剩余参数指的是函数调用时, 传入的参数个数不确定, 但最后一个参数必须是数组。

    • 用法: 使用(a, b,...arr), 可以将传入的参数收集到真数组中。

    • 作用: 可以实现函数的可变参数。

    javascript 复制代码
    function getSum(a, b, ...arr) {
      let sum = a + b;
      for (let i = 0; i < arr.length; i++) {
        sum += arr[i];
      }
      return sum;
    }
    
    let result = getSum(1, 2, 3); // 6

箭头函数

  • 定义: 箭头函数是 ES6 新增的一种函数, 与普通函数的区别在于, 箭头函数没有自己的 this, arguments, super, new.target, 并且没有原型链。
javascript 复制代码
// 普通的箭头函数
let add = (a, b) => {
  return a + b;
};
let result = add(1, 2); // 3

// 只有一个参数的箭头函数可以省略括号, 只有一个语句的箭头函数可以省略大括号, 并且有返回值
let add1 = (a) => a + 1;
let result1 = add1(1); // 2

// 返回一个对象
let obj = (name, age) => ({ name: name, age: age });

let resultObj = obj("Tom", 20); // {name: 'Tom', age: 20}
箭头函数参数
  • 箭头函数没有 arguments 对象, 不能使用 arguments.length, 不能使用 arguments[i]获取参数, 但有剩余参数。

  • 箭头函数不会创建自己的 this, 但可以使用上级作用域的 this。

解构赋值

数组解构

  • 定义: 将数组中的单元值快速依次批量赋值给变量。

  • 语法: let [变量 1, 变量 2, 变量 3] = 数组;

  • 注意: 当解构赋值的变量个数与数组的单元值个数不一致时, 多余的变量会被赋值为 undefined, 少于的变量会被忽略。

javascript 复制代码
/*普通数组解构*/
const arr = [1, 2, 3];
const [a, b, c] = arr;

/*交换变量的值*/
let x = 1;
let y = 2;
[x, y] = [y, x];
console.log(x, y); // 2 1

/*利用剩余参数*/
let [a, b, ...rest] = [1, 2, 3, 4, 5];
console.log(a, b, rest); // 1 2 [3, 4, 5]

/*防止undefined传递*/
let [a = 0, b = 0, c = 0] = [1, 2];
console.log(a, b, c); // 1 2 0

/*按需导入赋值*/
let [x, , y] = [1, 2, 3];
console.log(x, y); // 1 3

/*多维数组解构*/
let [a, b, [c, d]] = [1, 2, [3, 4]];
console.log(a, b, c, d); // 1 2 3 4

对象解构

  • 定义: 将对象中的属性值快速依次批量赋值给变量。

  • 语法: let {变量 1: 变量 2, 变量 3: 变量 4} = 对象;

  • 注意: 当解构赋值的变量个数与对象属性个数不一致时, 多余的变量会被赋值为 undefined, 少于的变量会被忽略。且变量名应该与属性名一致。

javascript 复制代码
/*普通对象解构*/
const obj = { name: "Tom", age: 20 };
const { name, age } = obj;

/*重新改名*/
const obj2 = { name: "Tom", age: 20 };
const { name: n, age: a } = obj2;
//      旧名  新名

/*对象数组的解构*/
const arr = [
  { name: "Tom", age: 20 },
  { name: "Jerry", age: 25 },
];
const [{ name, age }, { name: n, age: a }] = arr;

/*多级对象解构*/
const pig = {
  name: "小猪",
  family: {
    father: "爸爸",
    mother: "妈妈",
    sister: {
      Siname: "姐姐",
      Sname: "妹妹",
    },
  },
};

const {
  name,
  family: {
    father,
    mother,
    sister: { Sname, Siname },
  },
} = pig;

数组进阶

forEach 遍历

javascript 复制代码
let arr = [1, 2, 3];

arr.forEach(function (value, index) {
  console.log(value);
  console.log(index);
});

filter 过滤

javascript 复制代码
const arr = [1, 2, 3, 4, 5];

const newArr = arr.filter(function (value, index) {
  return value > 2;
});

map 映射

javascript 复制代码
const arr = [1, 2, 3, 4, 5];

const newArr = arr.map(function (value, index) {
  return value * 2;
});

reduce 归并

javascript 复制代码
const arr = [1, 2, 3, 4, 5];

const result = arr.reduce(function (prev, curr, index) {
  return prev + curr;
}, 0);// 如果有初值, 则作为第一次执行的 prev, 每一次循环的返回值作为下一次的 prev

find 找出第一个匹配项

javascript 复制代码
const arr = [1, 2, 3, 4, 5];

const result = arr.find(function (value, index) {
  return value > 2;
});

findIndex 找出第一个匹配项的索引

javascript 复制代码
const arr = [1, 2, 3, 4, 5];

const result = arr.findIndex(function (value, index) {
  return value > 2;
});

includes 判断是否包含

javascript 复制代码
const arr = [1, 2, 3, 4, 5];

const result = arr.includes(3);
相关推荐
大厂码农老A2 分钟前
你打的日志,正在拖垮你的系统:从P4小白到P7专家都是怎么打日志的?
java·前端·后端
im_AMBER4 分钟前
CSS 01【基础语法学习】
前端·css·笔记·学习
摇滚侠4 分钟前
Spring Boot 3零基础教程,深度理解 Spring Boot 自动配置原理,笔记11
spring boot·笔记·后端
艾菜籽18 分钟前
Spring MVC入门补充2
java·spring·mvc
爆更小哇28 分钟前
统一功能处理
java·spring boot
程序员鱼皮30 分钟前
我造了个程序员练兵场,专治技术焦虑症!
java·计算机·程序员·编程·自学
fanstering1 小时前
腾讯混元P3-SAM: Native 3D Part Segmentation
笔记·学习·3d·点云
n8n1 小时前
SpringAI 完全指南:为Java应用注入生成式AI能力
java·后端
ZHOUYUANN1 小时前
我用JavaScript复刻了某宝的小游戏动物大迁徙消消乐
前端·javascript·游戏开发
Asort1 小时前
JavaScript设计模式(十三)——责任链模式:构建灵活高效的请求处理链
前端·javascript·设计模式