Skip to content

高级开发(1)

1497字约5分钟

2024-07-18

垃圾回收机制

内存生命周期

提示

全局变量一般不会回收(关闭页面回收) 局部变量的值,不用了,会被自动回收掉

内存分配,系统自动为变量、函数、对象分配内存

内存使用,使用变量、函数时会读写内存

内存回收

垃圾回收算法

引用计数法(IE)

标记清除法(大多数浏览器)

函数参数

动态参数

相关信息

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

let num = 0
for (let i = 0; i < arguments.length; i++) {
	num = num + arguments[i]
}
console.log(num)
  1. arguments 是一个伪数组
  2. arguments 的作用是动态获取函数的实参

剩余参数

提示

建议使用剩余参数替代动态参数

注意

剩余参数方便将不确定数量参数表示为数组

//不要删除省略号
function fn(...c) {
	let num = 0
	for (let i = 0; i < c.length; i++) {
		num = num + c[i]
	}
	console.log(num)
}

fn(4, 1, 8, 9, 2)

参数默认值

相关信息

有实参用实参,没有用自己的默认值

function fn(a, b = 10) {
  console.log(a + b)
}

展开运算符

1️⃣ 在构造数组时,将其他数组或字符串展开

let arr1 = [3, 4]
let arr2 = [5, 6]
let arr = [...arr1, ...arr2, ...'abc']
// console.log(arr)

2️⃣ 为函数传递参数,能够将数组或字符串展开

let arr3 = [2, 8, 7, 5, 3]
function fn(...a) {
  console.log(a) // [2, 8, 7, 5, 3]
}
fn(...arr3) // fn(2, 8, 7, 5, 3)

// console.log(Math.max(2, 8, 7, 5, 3))
console.log(Math.max(...arr3))

3️⃣ 在构造字面量对象的时候,能够展开其他对象

let obj1 = { uname: 'zs', age: 20 }
let obj2 = { sex: '', height: 180, age: 30 }
let obj = {
  id: 100,
  ...obj1,
  ...obj2,
  weight: 75
}
console.log(obj)

函数参数

变量提升和函数提升

推荐阅读YanniLi写的前端面试必考—JavaScript变量提升和函数提升详解

变量提升

提示

Js编译过程会悄摸摸把声明提升到作用域开头

例如使用var声明变量

a = 6;
var a;
console.log(a);

实际编译执行的顺序如下

var a;   //变量提升
a = 6;	 //赋值的优先级低
console.log(a);

但是如果你写成下面代码

b = 3;
let b;  //const b也是一样
console.log(b);

警告

会报错的,let和const没有提升特点

注意

let 在声明前赋值,会出现暂时性死区

提示

提升会把函数放在最前面,其次是var声明变量

var a = 1000

function fn() {
    console.log(a) // undefined
    var a = 10
}

函数表达式并不会被提升

answer();

var answer = function question(){
    console.log(Boolean(1));   
}

闭包

  • 外层函数有一个变量
  • 内层函数使用外层函数的变量
function outer() {
	let a = 10
    
    //内曾函数使用变量a
	function fn() {
		console.log(a)
      }
	return fn
};

let xx = outer(); 

// 调用 xx() 相当于调用了 fn
xx();

箭头函数

建议阅读这一次,彻底搞懂箭头函数

警告

不能用于方法

箭头函数是匿名函数,不能构造函数

let fn = (a, b) => {
	console.log(12345)
}

它相当于函数

function fn(a,b){
    console.log(12345)
}

提示

如果形参只有一个,则可以省略小括号

如果函数体只有一行代码,可以省略大括号,并且表示return函数体

let fn = x => x * x
console.log(fn(8))

setTimeout(() => console.log(123), 1000)

注意

注意返回单个对象加括号

let fn = () => ({ uname: 'zs', age: 20 })

console.log(fn()

this

let abc = 'hello'
// console.log(this) // 全局中的this === window
// 箭头函数中,没有固定的this
// 箭头函数中,如果使用this,把this当做普通变量看待即可(按照作用域去查找)

document.querySelector('button').addEventListener('click', () => {
  console.log(abc) // hello
  console.log(this) // window
  // console.log(this.tagName)
})

解构赋值

相关信息

解构赋值是一种快速为变量赋值的简洁语法,本质上仍然是为变量赋值

数组解构

数组解构是将数组的单元值快速批量赋值给一系列变量的简洁语法

// 普通的数组
let arr = [1, 2, 3];
// 批量声明变量 a b c 
// 同时将数组单元值 1 2 3 依次赋值给变量 a b c
let [a, b, c] = arr;
console.log(a); // 1
console.log(b); // 2
console.log(c); // 3
  1. 赋值运算符 = 左侧的 [] 用于批量声明变量,右侧数组的单元值将被赋值给左侧的变量

  2. 变量的顺序对应数组单元值的位置依次进行赋值操作

  3. 变量的数量大于单元值数量时,多余的变量将被赋值为 undefined

  4. 变量的数量小于单元值数量时,可以通过 ... 获取剩余单元值,但只能置于最末位

  5. 允许初始化变量的默认值,且只有单元值为 undefined 时默认值才会生效

对象解构

对象解构是将对象属性和方法快速批量赋值给一系列变量的简洁语法

// 普通对象
const user = {
  name: '小明',
  age: 18
};
// 批量声明变量 name age
// 同时将数组单元值 小明  18 依次赋值给变量 name  age
const {name, age} = user

console.log(name) // 小明
console.log(age) // 18
  1. 赋值运算符 = 左侧的 {} 用于批量声明变量,右侧对象的属性值将被赋值给左侧的变量
  2. 对象属性的值将被赋值给与属性名相同的变量
  3. 对象中找不到与变量名一致的属性时变量值为 undefined
  4. 允许初始化变量的默认值,属性不存在或单元值为 undefined 时默认值才会生效

重要

对象的解构不看顺序,和顺序无关 保证【变量名 === 对象的键】即可实现解构

let person = {
  uname: 'zs',
  age: 34,
  dog: {
    name: '汪仔',
    age: 3
  },
  cat: {
    name: '小花',
    age: 2
  }
}

let { uname, cat: { name } } = person

console.log(uname, name)