一.作用域:
- 局部作用域:在函数内部声明的变量只能在函数内部访问,函数的参数是函数内部的局部变量
- 块级作用域:用{}包裹的代码成为代码块,let 和const会产生作用域,var不会
- 全局作用域:全局有效,作用在整个script标签中和JS文件的最外层
作用域链:
作用域的本质是:底层的变量查找机制
在函数被执行时,会优先查找当前函数作用域中查找变量,如当前作用域找不到会依次逐渐查找 父 元素作用域直到全局作用域,子元素能访问父作用域,父作用域不能访问子作用域
JS垃圾回收机制:
- 垃圾回收机制是JS中内存分配和回收都是自动完成的,内存不适用的时候会被垃圾回收机器自动回收
- 不再用到的内存,没有及时释放,就叫内存泄漏
- 全局变量一般不会回收(关闭网页回收),局部变量的值,不用了,会被自动回收掉
- 内存声明周期:内存分配,内存使用,内存回收
- 内存回收机制分为:引用计数,标记清除法
二.闭包
闭包就是内层函数+外层函数的变量
作用:封闭数据,提供操作,外部也可以访问函数内部的变量
闭包缺点:存在内存泄漏,占据内存
// 闭包的作用:延长局部变量的生命周期,让局部变量活的久一些
// 缺点:占据内存
function f1() {
let i = 10
function f2() {
i++
console.log(i);
}
return inner
}
let f = f1() //调用 f1函数 得到f1 函数的 返回值 将返回值赋值给全局变量f
f() //等价于 调用f2函数 f2 函数在 访问 f1 所以f1 里面的变量i 没有被销毁
变量提升:
var声明的变量会提升到当前作用域的最前面,只提升声明不提升赋值.
三.函数进阶:
- 函数提升:会把所有函数声明提升到当前作用域的最前面,只提升函数声明,不提升函数调用.
- 函数表达式,必须先声明赋值,后调用,否则报错
- 函数参数:arguments 动态参数,只存在函数里面 是个伪数组
// 当我们不确定形参有多少个时, 就不写形参, 可以使用arguments 可以获取所有的实际参数 得到的是伪数组
function getSum() {
let sum = 0
// 遍历arguments 伪数组
for (let i = 0; i < arguments.length; i++) {
sum += arguments[i]
}
console.log(sum)
}
getSum(1, 2, 3, 4, 5, 6)
getSum(3, 4, 10, 8)
- 剩余参数:借助...变量名获取剩余参数,是一个真数组
// 剩余参数就是不知道实参传递几个过来时 使用 将剩余的参数传递到数组里,是个真数组
// function fn(...arr) {
// let sum = 0
// for (let i = 0; i < arr.length; i++) {
// sum += arr[i]
// }
// console.log(sum)
// }
// fn(1, 2, 3, 4, 5)
function f(a, ...arr) {
arr.pop()
console.log(arr)
}
f(4, 5, 6, 7, 8, 9)
- 展开运算符:将一个数组展开,在数组中使用,可以求最大值以及合并数组等
const arr = [1, 2, 3, 4, 5, 6, 7] // 将数组里面的数字展开 // console.log(...arr) // 展开运算符 可以用于合并数组 // const arr1 = [1, 2, 3, 4] // const arr2 = [5, 6, ...arr1] // // 展开运算符 可以用于求数组的最大值和最小值 // Math.max() const res = Math.max(...arr) console.log(res)
箭头函数:
- 基本语法:const fn= ()=>{函数体}
- 只有一个形参时可以省略小括号
- 只有一行代码时可以省略大括号,省略retrue
// 箭头函数 优化函数表达式的方法
// const fn = function () {
// console.log(1);
// }
// const fn = () => {
// console.log(1)
// }
// fn()
// // 只有一个形参时可以省略小括号
// const fn1 = x => {
// console.log(1)
// }
// 如果函数体 只有一行代码 需要将函数里面的得到结果 返回 函数体的大括号
// 可以省略不写 同时return关键字 可以省略不写
// const getSum = function (x, y) {
// return x + y
// }
const getSum = (x, y) => x + y
const re = getSum(10, 20)
console.log(re);
- 加括号的函数体返回对象字面量表达式
- 箭头函数参数:没有arfuments,只有剩余参数
// 获取所有的实际参数
// 🔔箭头函数里面没有arguments 有剩余参数
const fn = (...arr) => {
let sum = 0
for (let i = 0; i < arr.length; i++) {
sum += arr[i]
}
console.log(sum)
}
fn(1, 2, 3, 45, 6, 4)
fn(1, 2, 3)
- 箭头函数不会创建自己的this,他只会在自己的作用于链的上一层沿用this.
// 箭头函数里面 不会创建自己的this 只会在上一级作用域链的上一层沿用this const btu = document.querySelector('#btu') // 事件注册处理函数, 尽量不要使用箭头函数 btu.addEventListener('click', () => console.log(this))
四:解构赋值
数组解构:
数组解构赋值作用:将数组的单元值快速批量赋值给一系列变量
. 变量的数量大于单元值数量时,多余的变量将被赋值为undefined
变量的数量小于单元值数量时,可以通过剩余参数... 获取剩余单元值,但只能置于最末位
const pc = ['海尔', '联想', '小米', '方正']
const [hr, lx, mi, fz] = pc
console.log(hr, lx, mi, fz)
function getValue() {
return [100, 60]
}
const [max, min] = getValue()
console.log(max, min)
Js 前面有两哪种情况要加分号:
- 立即执行函数
- 数组解构
对象解构:
对象解构是将对象属性和方法快速批量赋值给一系列变量的简洁语法
使用对象解构的变量名必须与属性名一样
/ 使用对象解构的时候 变量名必须和属性名一样
// 对象解构:快速将对象里面的属性值 赋值给变量的一种简洁语法
const obj = {
name: '张三',
age: 18
}
const { name:uname, age } = obj
console.log(uname)
console.log(age)
// 数组结构是将数组的单元值快速批量给一系列变量的简介语法
// 多维数组
const arr = [1, 2, 3, [4, 5]]
const [a, b, c, [d, e]] = arr
console.log(d)
遍历数组forEach方法:
forEach()方法遍历数组的每一个元素,并将元素传递给回调函数
const arr = [1, 2, 3, 4, 5,]
let sum = 0
// arr.forEach(function (item) {
// sum += item
// })
arr.forEach(item => sum += item)
console.log(sum)
筛选数组filter方法:
filter()方法创建一个新的数组,数组中的元素是通过检查数组中符合条件中的所有元素,并返回筛选之后的元素新数组
// 从数组里面筛选大于等于20的数组元素
const arr = [10, 15, 18, 20, 25, 33, 66, 88]
// const newArr = arr.filter((item){
// return item >= 20
// })
const newArr = arr.filter(item => item >= 20)
console.log(newArr)
// 根据条件 返回新的数组元素
// 数组名.filter(function (数组的元素, 数组的索引, 数组本身) { })