作用域:
1. 局部作用域:
函数作用域: 只有函数内部才能被访问, 函数执行完毕,变量就被清除
块作用域: let, const {}, for{}, if{}里面的变量.
有可能被访问, 比如var 不用产生块作用域.
2. 全局作用域: <script> .js文件都可以访问.
作用域链: 本质是底层的变量查找机制.
1. 函数被执行时, 会优先查找当前函数作用域来查找变量.
2. 当前作用域查不到会依次逐级查找父级作用域直到全局作用域.
注意:
子级可以访问父级作用域, 继承;
父级不能访问子级作用域.
垃圾回收机制(GC): js中内存分配和回收都是"自动完成"的,内存在不使用的时候就会被垃圾回收机制自动回收.
内存的生命周期:
1. 内存分配
2. 内存使用
3. 内存回收(局部变量的值, 不用会被自动回收掉)
内存泄漏: 程序中分配和内存由于某种原因程序未释放的或无法释放.
---
闭包: 一个函数对周围状态的引用捆绑在一起,内层函数中访问到其外层函数的作用域.
内层函数+外层函数的变量.
闭包作用: 封闭数据,提供操作,外部也可以访问函数内部的变量.
function outer(){
let a = 10;
function fn(){
console.log(a)
}
return fn;
}
//outer() === fn === function fn(){}
const fun = outer()
fun()//外部函数使用函数内部的变量
注意: 存在闭包, 将有些变量私有化,避免被修改.
变量提升:
1. 把所有var声明的变量提升到 当前作用域的最前面
2. 只提升声明,不提升赋值
console.log(num)
var num = 10;
//输出 undefined 因为只提升声明,没有提升赋值操作.
---
函数提升:
1. 会把所有函数声明提升到当前作用域的最前面
2. 只提升声明, 不提升函数调用.
函数参数:
1. 动态参数:不知道具体有多少个参数的时候使用!
arguments是函数内部内置的伪数组变量, 它包含了调用函数时传入的所有实参.
function getSum(){
let s = 0;
for(let i = 0; i < arguments.length; i++)
{
s += agruments[i]
}
console.log(s);
}
getSum(2,3,4)
//输出 9
2. 剩余参数: 使用多余的参数. 在函数内使用
...来引入参数
function getSum(...arr){
let s = 0;
for(let i = 0; i < arr; i++)
{
s += arr[i]
}
console.log(s);
}
getSum(2,3,4)
//输出 9
注意:
... 是语法符号,置于最末函数形参之前,用于获取多余的参数
借助... , 获取的是真数组.
展开运算符(...): 可以展开数组 , 在数组中使用
一般用于取最大值,最小值,合并数组等
const arr = [1, 2, 3]
//...arr === 1,2,3
console.log(Math.max(...arr))//输出为3
console.log(Math.min(...arr))//输出为1
//合并数组
const arr1 = [4,5,6]
const arr2 = [...arr,...arr1]
console.log(arr2)
箭头函数:用简短的函数写法并且不绑定this,一般用于需要匿名的地方.
语法:
const fn = () => {
console.log(123)
}
fn()
//一个参数
const fn = (x) => {
console.log(123)
}
fn(1)
//只有一行代码,可以省略大括号,一个参数可以省略括号
const fn = x => console.log(x)
//箭头函数可以直接返回一个对象, ()区分{}
const fn = (uname) => ({uname: uname})
fn('ly')
箭头函数参数:
箭头函数只有...剩余参数,没有arguments动态参数.
注意:
普通函数this指向window (谁调用这个函数, this就指向谁)
箭头函数不会创建自己的this, 指向上一层作用域的this.
---
解构赋值:
1. 数组解构 : 将数组的单元值快速批量赋值给变量的简洁语法.
语法: 赋值运算符 = 左侧的[] 用于批量声明变量.
const arr = [100, 20, 50];
const [max, min, avg] = arr
//还可以交换变量, 不用引入第三个变量
let a = 1;
let b = 2;
[b, a] = [a, b]
注意:
js必须加分号的两种情况:
1. 立即执行函数
(function(){})();
(function(){})();
2. 使用数组的时候
const arr = [1, 2, 3];
const [max, min, avg] = arr
防止有undefined传递单元值的情况可以设置默认值.
2. 对象解构: 将对象的属性和方法快速批量赋值给一系列变量的简洁语法.
语法:
//声明变量名必须和属性名一致
const {uname, age} = {uname: 'ly', age: 18}
//等价于: const uname = obj.uname
---
//对象解构变量名可以重新改名 ,旧变量名: 新变量名
const {uname : username, age} = {uname: 'ly', age: 18}
数组对象解构:
const arr = [
{
uname: 'ly',
age: 18
}
]
const [{uname, age}] = arr
多级对象解构:
const arr = {
name: 'ly',
obj: {
age: 18,
price: 1000
}
}
const {name, obj: {age, price}} = arr
---
遍历数组forEach方法:调用数组的每个元素,并将元素传递给回调函数.
语法:
被遍历的数组.forEach(function(当前数组元素, 当前元素索引号) {
//函数体
})