JavaScript进阶--作用域-函数进阶

Javascript进阶

作用域

分类

  • 局部
    • 函数 ==>执行完变量被清空
    • 块 ==>用{}包住 ==>有可能被无法访问 【用var声明的变量】
  • 全局 ==> 在script标签和.js文件最外层进行声明

作用域链

最底层的变量查找机制 ==> 在函数被执行时,会优先查找当前函数作用域中查找变量,找不到再找父级作用域

垃圾回收机制 Garbage Collection

JS中内存的分配和回收都是自动完成的

内存的生命周期

内存分配–>内存使用 -->内存回收

全局变量一般不会回收,直至关闭页面

内存泄漏

程序中分配内存未释放或无法释放由于某种原因

JS垃圾回收机制 - 算法说明

堆和栈

  • 栈:操作系统自动分配函数参数局部变量【基本数据类型】
  • 堆:由程序员分配释放,或者通过垃圾回收机制【复杂数据类型】
引用计数法【基本不使用了】

若对象无指向它的引用,进行回收

[!NOTE]

设置count变量来保存对于某变量的引用次数,引用一次自增,减少引用自减,当count变为0,释放内存

引用的意思是是否有变量名或者指针保存复杂数据类型变量的地址

若复杂数据类型互相指向,则count永不为0,导致内存泄漏

标记清除法

从根部(即

闭包 - closure

简单理解:内层函数 use–> 外层函数变量

作用

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

闭包机制

 function folder() {
      let a = 1
      function fn() {
        console.log(a)
      }
      fn()
    }
    folder()

效果为

在这里插入图片描述

右边的Closure就是所谓的闭包

Local:局部变量

Global:全局变量

常见闭包形式

function outer() {
      let a = 1
      function inner() {
        console.log(a);
      }
      return inner;
    }
    let b = outer();
    b(); // 1

[!IMPORTANT]

相当于外部函数可以调用inner()函数,间接使用到,修改到函数内部变量,但不会让外部直接堆变量进行修改

借此实现数据的私有。 但由于始终可以查找到变量,导致变量无法被释放,产生内存泄漏的问题

变量提升

允许变量声明之前被访问(var声明变量)

const和let声明的变量不会出现这种情况

内部会先检查有无var声明的变量,若有,则将声明提前,赋值不会提前

 console.log(a); // undefined
    var a = 10;
    console.log(a); // 10

在这里插入图片描述

函数进阶

函数提升

函数在声明之前可以被调用(在同等作用域下,提到最前面)

若被调用的函数为赋值得到的,则不可行,因为变量提升只提升声明,不含赋值

 // 函数提升
    fn()
    function fn() {
      console.log('函数提升')
    }
    // 变量提升
    fun()
    var fun = function () {
      console.log('变量提升')
    }

函数参数

动态参数

函数内置 arument

  • 伪数组
  • 只存在函数中

调用时有参数,定义时括号内无参数

 function addAll() {
      let sum = 0;
      for (let i = 0; i < arguments.length; i++) {
        sum += arguments[i];
      }
      return sum;
    }
    console.log(addAll(1, 2, 3, 4, 5)); //15
    console.log(addAll(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)); //55
剩余参数

将不定数量的多余实参变为一个真数组

function sum(a, b, ...rest) {
      let result = a + b;
      for (let i = 0; i < rest.length; i++) {
        result += rest[i];
      }
      return result;
    }

    console.log(sum(1, 2, 3, 4, 5)); // 15
    console.log(sum(1, 2)); // 3
    console.log(sum(1, 2, 3, 4, 5, 6)); // 21
展开运算符

...将数组展开(或者对象等)

应用

  • 求数组最大组 --Math.max()
  • 合并数组
const arr = [1, 2, 3, 4, 5]
    console.log(...arr)
    console.log(Math.max(...arr))
    console.log(Math.min(...arr))
    const arr1 = [1, 2, 3, 4, 5]
    const arrAll = [...arr1, ...arr]
    console.log(...arrAll)

箭头函数

以更简洁的方式写匿名函数

语法技巧

  • 只有一个参数,可以省略括号
  • 函数只有一行代码可以省略大括号
  • 只有一句return语句,可省略return
  • 可用来返回对象
 // 箭头函数
    const add = (a, b) => {
      console.log(a + b);
      return a * b
    }
    add(2, 3); // 5
    const double = a => a * 2;
    double(3); // 6
    const item = (uname) => ({ name: uname })
    console.log(item('John'))
    // {name: 'John'}

只可以用剩余参数

const all = (...arr) => console.log(...arr);
    all(1, 2, 3, 4, 5); // 1 2 3 4 5

不会创建自己的this,只会从自己的作用域的上一层沿用this

回调函数不推荐使用箭头函数

//this指向
    const a1 = () => this
    console.log(a1()); // window
    const a2 = function () {
      let i = 1
      const a3 = () => this
      console.log(a3()); // window
    }
    a2();
    const obj = {
      uname: "shaly",
      sayName: () => this
    }
    console.log(obj.sayName()) // shaly
    const obj2 = {
      uname: "shaly",
      sayName: function () {
        const a4 = () => this
        console.log(a4())
      }
    }
    console.log(obj2.sayName())
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值