一.变量提升
变量提升是JavaScript中比较"奇怪"的现象,它允许在变量声明之前即被访问(仅存在于var声
明变量)
javascript
<body>
<script>
//把所有var声明的变量提升到 当前作用域的最前面
//只提升声明,不提升赋值
//var num
console.log(num + '个');
//num = 10
var num = 10
console.log(num)
</script>
</body>

javascript
<body>
<script>
function fn(){
console.log(num);
var num = 100
}
fn()
</script>
</body>

1.变量在未声明即被访问时会报语法错误
2.变量在var声明之前即被访问,变量的值为undefined
3.let/const 声明的变量不存在变量提升
4.变量提升出现在相同作用域当中
5.实际开发中推荐先声明再访问变量
二.函数提升
函数提升与变量提升比较类似,是指函数在声明之前即可被调用
javascript
<body>
<script>
//会把所有函数声明提升到当前作用域的最前面
//只提升函数声明,不提升函数调用
fn()
function fn(){
console.log('函数提升');
}
</script>
</body>

javascript
<body>
<script>
//函数表达式 必须先声明和赋值,后调用,否则报错
fn()
var fn = function (){
console.log('函数提升');
}
</script>
</body>

1.函数提升能够使函数的声明调用更灵活
2.函数表达式不存在提升的现象
3.函数提升出现在相同作用域当中
三.函数剩余参数
1.动态参数:
arguments 是函数内部内置的伪数组变量,它包含了调用函数时传入的所有实参
arguments动态参数只存在于函数里面
javascript
<body>
<script>
function getSum(){
console.log(arguments);
}
getSum(1,2,3,4,5)
</script>
</body>

javascript
<body>
<script>
function getSum(){
console.log(arguments);
let sum = 0
for(let i = 0;i<arguments.length;i++){
sum += arguments[i]
}
console.log(sum);
}
getSum(1,2,3,4,5)
</script>
</body>

1.arguments是一个伪数组,只存在于函数中
2.arguments的作用是动态获取函数的实参
3.可以通过for循环依次得到传递过来的实参
4.当不确定传递多少个实参的时候,可以使用arguments动态参数
2.剩余参数:
剩余参数允许我们将一个不定数量的参数表示为一个数组(存在于函数中)
javascript
<body>
<script>
function getSum(...arr){
console.log(arr);
}
getSum(1,2,3)
getSum(1,2,3,4,5)
</script>
</body>

- ...是语法符号,置于最末函数形参之前,用于获取多余的实参
2.借助...获取的剩余实参,是个真数组
3.开发中,还是提倡多使用剩余参数
javascript
<body>
<script>
function getSum(a,b,...arr){
console.log(arr);
}
getSum(1,2,3,4,5)
</script>
</body>

四.展开运算符
展开运算符(...),将一个数组进行展开(函数、对象、数组都可以使用),不会修改原数组
javascript
<body>
<script>
const arr = [1,2,3,4,5,8,6,12,4]
console.log(...arr);
</script>
</body>

典型运用场景:求数组最大值(最小值)、合并数组等
javascript
<body>
<script>
const arr = [1,2,3,4,5,8,6,12,4]
console.log(Math.max(...arr));
</script>
</body>

javascript
<body>
<script>
const arr1 = [1,2,3,4,5,8,6,12,4]
const arr2 = [2,3,11,9,10,15]
const arr = [...arr1,...arr2]
console.log(arr);
</script>
</body>

展开运算符 和 剩余参数 的区别:
展开运算符:主要在数组中使用,数组展开
剩余参数:函数参数使用,得到真数组,函数内部使用
五.箭头函数
引入箭头函数的目的是更简短的函数写法 并且不绑定this,箭头函数的语法比函数表达式更简洁
使用场景:箭头函数更适用于那些本来需要匿名函数的地方
1.基本写法:
javascript
<body>
<script>
// 普通写法
const fn = function(){
console.log(123);
}
fn()
// 箭头函数写法1
const fun = () => {
console.log(456);
}
fun()
// 箭头函数写法2
const fun2 = a => {
console.log(a);
}
fun2(100)
// 只有一行代码时,可以省略大括号和return关键字
const fun3 = a => console.log(a)
fun3(100)
// 箭头函数写法3
const fun4= (a,b) => {
console.log(a+b);
}
fun4(20,200)
// 箭头函数可以直接返回一个对象
const fun5 = (uname) =>({uname:uname})
fun5('张三')
console.log(fun5('张三'));
</script>
</body>

1.箭头函数属于表达式函数,因此不存在函数提升
2.箭头函数只有一个参数时可以省略圆括号()
3.箭头函数函数体只有一行代码时可以省略花括号{},并自动做为返回值被返回
4.加括号的函数体返回对象字面量表达式
2.箭头函数参数:
1.普通函数有arguments动态参数
2.箭头函数没有arguments动态参数 ,但是有剩余参数..args
javascript
<body>
<script>
const getSum = (...arr) => {
let sum = 0
for(let i=0;i<arr.length;i++){
sum += arr[i]
}
return sum
}
const res = getSum(1,2,3,4,5);
console.log(res);
</script>
</body>

3.箭头函数this:
箭头函数不会创建自己的this,它只会从自己的作用域链的上一层沿用this
javascript
<body>
<script>
console.log(this); // window
function fn(){
console.log(this); // window
}
fn()
const obj ={
name:'张三',
say(){
console.log(this); // obj
}
}
obj.say()
const fun = () => {
console.log(this); // window
}
fun()
const obj2 ={
name:'李四',
say2:()=>{
console.log(this); // window
}
}
obj2.say2()
const obj3 ={
name:'王五',
say3:function(){
let i = 5
const count = () => {
console.log(this); // obj3
}
count()
}
}
obj3.say3()
</script>
</body>

在开发中使用箭头函数前需要考虑函数中this 的值,事件回调函数使用箭头函数时,this为全局的
window,因此DOM事件回调函数为了简便,还是不太推荐使用箭头函数