作用域分类
- 作用域分为局部作用域和全局作用域 ;局部作用域:函数内部的作用域 ;全局作用域:函数外部的作用域
- 变量分为局部变量和全局变量
- 函数调用执行时,都会开辟新的内存空间,当函数执行完毕就会关闭这块空间,并且里面的一些变量也会被销毁
- -声明变量可以不写let 此时的变量是全局变量
局部作用域
- 局部变量:在函数内部声明的变量就是局部变量 局部变量只能在当前函数内部使用;在函数执行完毕时会关闭局部作用域空间,局部变量会被销毁
- 函数中的形参:形参相当于局部变量
ES6新增的块级作用域
- 块级作用域:相当于局部作用域;用{
}包起来的代码块,就是块级作用域
- 全局变量哪里都能使用,所以尽量少用全局变量
定义变量的三种关键字
var
- var声明的变量没有块级作用域
- var允许重复声明同一个变量 后面的变量覆盖前面的
- var声明的变量相当于给window添加属性,是属于window的;而let直接就是变量
- var和let只定义不赋值 都是undefined
eg:
var a = 3;
console.log(window);
-
let
- let声明的变量具有块级作用域
- let不允许在同一块作用域下重复声明同一个变量
const
- const声明的变量不允许再改变,成为常量
- const定义的常量必须初始化赋值
- const定义的常量在初始化赋值之后不允许在重新赋值
- 建议:const 定义的常量全都大写表示
- 其他的特性和let没有区别;即也有块级作用域
作用域链
作用域链的定义
- 定义:由作用域链串联起来的链状结构
- 作用:提供查找变量的一种机制
- 注意:串联过程是子作用域逐层向父作用域推进的
分析1
<script>
let n = 2;
function fn() {
n = 3;
console.log(n);
}
fn(); // 3
console.log(n);//3
//判断fn函数是否有n: fn在函数中是否用let等关键字声明,如果没有用关键字声明则算没有n;fn中的n=3时赋值不是声明
//分析:在调用函数后,执行fn()函数;在fn函数中查询是否声明过变量n【用关键词let,var声明】;如果在fn函数中没有找到声明的变量n 就会取上一级作用域去查找 找到后 函数内n=3是于对找到的 let n重新赋值 最后调用函数执行 打印的结果就是3
//函数调用之后 再打印n 返回结果是3 ;原因就是:执行调用函数时,全局变量n的值已经被修改为3了
//总结:如果在当前的作用域内不存在一个声明变量的话,就会去上一个作用域查找;如果所有的上级都找不到 则会报错
</script>
分析2
let num = 1;
function f1() {
num = 2;
function f2() {
num = 3;
}
f2();
}
f1();
console.log(num);//3
//分析:当前全局变量num是1,f1调用执行f1函数----在f1函数中,执行到num=2语句:此时f1函数在自己作用域中找num,没有找到,然后去上一级找 找到了let num=1,所以更新之后全局变量let num=2了-----接着f2函数被调用,执行nu