今日是JavaScript高阶笔记,简单的提升笔记,望大家共同进步,(学习前端的小菜鸟一个)
作用域: 代码起作用的区域
☞全局作用域: 函数外部都是全局作用域
定义的变量(全局变量), 在任何的地方访问
☞局部作用域: 函数内部就是局部作用域
在局部作用域中定义的变量(局部变量), 只能在当前作用域中使用
function fn() {
let a = 123;
return a;
}
☞块级作用域: {} let 或者 const关键字
在块级作用域中定义的变量, 只能在当前作用域中使用
if (true) {
let a = 1
}
作用域链
作用: 在程序中指导变量查找规则
作用域链: 当程序在执行变量的时候,先在当前作用域中查找是否有变量,如果有则执行当前作用域中变量, 如果没有则沿着作用域链向上一级继续查找,找到为止
在嵌套作用域中,多个作用域形成链状结构 ---> 作用域链
函数提升 + 变量提升
函数提升:
在程序中遇到函数的时候, 自动将函数的声明提升到当前作用域的开始位置, 不包含函数的调用
// 函数提升案例
fn();
function fn() {
console.log(123);
}
变量提升: 返回值为 undefined
使用var关键字定义的变量, 那么会将变量的声明提升到当前作用域的开始位置, 不包含变量的赋值
let 没有变量提升
变量提升案例
结果 ? 报错 原因: let 关键字定义的变量, 必须先定义后使用.let关键字定义的变量, 没有变量提升
console.log(a);
let a = 123;
原因 ? undefined 原因: var 关键字声明的变量有变量提升
console.log(b);
var b = 123;
闭包函数: 在函数fn中, 通过另外一个函数fn1使用了当前函数fn中的变量, 整体fn就叫闭包函数
例: fn1中调用了a, 局部作用域中没有就向上寻找父级元素的a并调用, 此时整个fn都叫闭包函数
function fn() {
let a = 123;
function fn1() {
return console.log(a + 1);;
}
fn1();
}
fn();
函数参数默认值
为防止出现实参与形参数量不同而出现undefined, 给形参设置0的默认值
function fn(a = 0, b = 0) {
return a + b;
}
fn();
// arguments 伪数组s
☞ 在函数中用来保存实参信息的伪数组
☞ arguments.length 保存了实参的个数
☞ 通过循环遍历 arguments[索引] 得到具体实参的值
☞ 当形参个数不确定的时候, 使用arguments获取实参
// 例:
function cc() {
for (let i = 0; i < arguments.length; i++) {
console.log(arguments[i]);
}
}
cc('aa', 'cc', 'pp')
// 剩余参数: ...参数名
☞ 在函数中通过 ...参数名
☞ 剩余参数最后是以数组形式存在的
☞ 剩余参数保存的也是实参的值
☞ 剩余参数必须写到形参的最后
// 例:
function fn(a, b, ...d) {
// d 是剩余参数
console.log(d);
}
fn(1, 2, 3, 4)s
// 箭头函数:
☞ (形参1, 形参2) => { 函数体 }
☞ 按照自调用函数写法, 调用箭头函数((形参1, 形参2) => { 函数体 })();
☞ 将箭头函数赋值给一个变量, 通过 变量名() 调用;
☞ 如果只有一个形参, 则() 可以省略 形参1 => { 函数体 }
☞ 如果函数体中只有一行代码, 则 { } 可以省略. (形参1, 形参2) => 函数体
☞ 如果函数体中只有一行代码且有返回值, 则 { } 和 return 可以省略
☞ 箭头函数中的this, 指向上级作用域中this的事件源
// 例:
let btn = document.querySelector('button')
btn.onclick = function () {
let anniu = () => {
console.log(this);
}
anniu()
}
// let const var
const关键字: 定义常量的(1, 常量的值不能修改 2, 定义常量必须设置默认值, 3, cosnt会形参块级作用域)
var关键字: 定义变量的(1. 变量可以先使用后定义 2, 变量提升 3 不会形成块级作用域)