1. 作用域
1.1 局部作用域
局部作用域分为函数作用域和块作用域({ })
- var是函数作用域
- const,let是块作用域
1.2 全局作用域
<script>
和js文件 的最外层是全局作用域
1.3 作用域链
1.4 js垃圾回收机制
引用计数法
标记清除法
1.5 闭包
-
概念:一个函数对周围状态的引用捆绑在一起,内层函数中访问到其外层函数的作用域
-
简单理解:闭包 = 内层函数 + 外层函数的变量
-
闭包作用:封闭数据,提供操作,外部也可以访问函数内部的变量
-
闭包的基本格式:
- 闭包应用:实现数据的私有
1.6 变量提升
变量提升是 JavaScript 中比较“奇怪”的现象,它允许在变量声明之前即被访问(仅存在于var声明变量)
把所有 var 声明的变量提升到 当前作用域 的最前面,但只提升声明,不提升赋值
<script>
console.log(num + 1);//NaN
var num = 1
</script>
注意:
-
变量在未声明即被访问时会报语法错误
-
变量在var声明之前即被访问,变量的值为 undefined
-
let/const 声明的变量不存在变量提升
-
变量提升出现在相同作用域当中
-
实际开发中推荐先声明再访问变量
2.函数进阶
2.1 函数提升
函数提升与变量提升比较类似,是指函数在声明之前即可被调用。
注:
-
函数提升能够使函数的声明调用更灵活
-
函数表达式不存在提升的现象
函数表达式相当于赋值,赋值不提升
-
函数提升出现在相同作用域当中
2.2 函数参数
动态参数
arguments
是函数内部内置的伪数组变量,它包含了调用函数时传入的所有实参
-
arguments 是一个伪数组,只存在于函数中
-
arguments 的作用是动态获取函数的实参
-
可以通过for循环依次得到传递过来的实参
function sum() {
console.log(arguments);
}
sum(0, 1, 2)
function sum() {
let sum = 0
for (let i = 0; i < arguments.length; i++) {
sum += arguments[i]
}
console.log(sum);
}
sum(1, 2, 3, 4, 5, 6)
sum(5, 7, 9, 2)
剩余参数 (提倡使用)
剩余参数允许我们将一个不定数量的参数表示为一个数组
-
... 是语法符号,置于最末函数形参之前,用于获取多余的实参
-
借助 ... 获取的剩余实参,是个真数组,只存在函数中
function sum(a,b,...arr) {
console.log(arr);
}
sum(1, 2, 3, 4, 5, 6)
sum(5, 7, 9, 2)
</script>
展开运算符
展开运算符(…),将一个数组进行展开
说明:不会修改原数组
典型运用场景: 求数组最大值(最小值)、合并数组等
展开运算符 or 剩余参数:
- 剩余参数:函数参数使用,得到真数组
- 展开运算符:数组中使用,数组展开
2.3 箭头函数
-
目的:引入箭头函数的目的是更简短的函数写法并且不绑定this,箭头函数的语法比函数表达式更简洁
-
使用场景:箭头函数更适用于那些本来需要匿名函数的地方
/* const fn=function(){
console.log(123);
} */
// 1.箭头函数
const fn = (n) => {
console.log(n);
}
fn(1)
// 2.只有一个形参时,可省略小括号
const fn = n => {
console.log(n);
}
// 3.只有一行代码时,可省略大括号
const fn = n => console.log(n);
// 4.只有一行代码时,可省略 return
/* const fn = n => {
return n + n
} */
const fn = n => n + n
console.log(fn(1));
// 5.箭头函数可以直接返回一个对象
/* const fn = function (uname) {
return {
name: uname//返回:name: 'zhangsan'
}
} */
const fn = uname => ({ name: uname })
console.log(fn('zhangsan'));
箭头函数参数
-
普通函数有
arguments 动态参数
-
有
剩余参数 ..args
const fn = (...arr) => {
let sum = 0
for (let i = 0; i < arr.length; i++) {
sum += arr[i]
}
console.log(sum);
}
fn(1, 2, 3, 5, 9)
箭头函数的this
-
之前:this指向函数的调用者
-
箭头函数不会创建自己的this,它只会从自己的作用域链的上一层沿用this。
// 1. 箭头函数的this
const fn = () => {
console.log(this);//指向 window
}
fn()
//2. 对象方法的箭头函数的this
const obj = {
name: 'zhangsan',
// 第一种情况
habbit: () => {
console.log(this);//上一层作用域是 obj对象,因此this指向 window
},
// 第二种情况
sayhi: function () {
console.log(this);//指向 obj
const fn = () => {
console.log(this);//上一层作用域是function函数,this指向 obj
}
fn()
}
}
obj.habbit()
obj.sayhi()
2.4 解构赋值
数组解构
数组解构是将数组的单元值快速批量赋值给一系列变量的简洁语法。
基本语法:
- 赋值运算符 = 左侧的 [] 用于批量声明变量,右侧数组的单元值将被赋值给左侧的变量
- 变量的顺序对应数组单元值的位置依次进行赋值操作
① 变量多 单元值少的情况:
可以使用剩余函数:
② 变量少 单元值多的情况:
③ 防止有undefined传递单元值的情况,可以设置默认值:
④ 按需导入,忽略某些返回值:
多维数组解构
对象解构
对象解构是将对象属性和方法快速批量赋值给一系列变量的简洁语法
基本语法:
-
赋值运算符 = 左侧的 {} 用于批量声明变量,右侧对象的属性值将被赋值给左侧的变量
-
对象属性的值将被赋值给与属性名相同的变量
-
注意解构的变量名不要和外面的变量名冲突否则报错
-
对象中找不到与变量名一致的属性时变量值为 undefined
const obj = {
uname: 'zhangsan',
age: 18
}
console.log(obj.uname);
// 解构赋值
const { uname, age } = {
uname: 'zhangsan',
age: 18
}
console.log(uname);
给新的变量名赋值:
可以从一个对象中提取变量并同时修改新的变量名
{旧变量名:新变量名}
多级对象解构
const pig = {
name: '佩奇',
family: {
mother: '猪妈妈',
father: '猪爸爸',
sister: '乔治'
},
age: 6
}
const { name, family: { mother, father, sister }, age } = pig
console.log(mother);
案例:
const msg = {
'data': [
{
id: 1,
name: 'zhangsan'
},
{
id: 2,
name: 'lisi'
},
{
id: 3,
name: 'wangwu'
}
]
}
//msg传给函数,输出data
/* const { data } = msg;
function fn(arr) { */
// {data} = msg = arr
function fn({ data }) {
console.log(data);
}
fn(msg)
3.遍历数组 forEach 方法(重点)
-
forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数
-
主要使用场景: 遍历数组的每个元素
一个小案例
<ul>
</ul>
<script>
const ul = document.querySelector('ul');
let str = ''
const arr = [
{ id: 1, name: 'zhangsan' },
{ id: 2, name: 'lisi' },
{ id: 3, name: 'wangwu' }
]
arr.forEach(item => {
//item是一个对象,将item解构赋值
const { id, name } = item
// 用拼接字符串的形式
str += '<li>id是' + id + ',姓名是:' + name + '</li>'
ul.innerHTML = str
})
</script>
4.筛选数组 filter 方法(重点)
-
filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素
-
主要使用场景: 筛选数组符合条件的元素,并返回筛选之后元素的新数组
案例:
标签:console,函数,作用域,高级,JS,const,fn,log From: https://www.cnblogs.com/mtdj/p/16721971.html