一.怎么是作用域
- 作用域就是变量生效的范围
- 作用域的用处是隔离变量,不同作用域下的同名变量不会冲突
二.全局作用域
在代码中任何地方都能访问到的对象拥有全局作用域:
- 最外层函数 和在最外层函数外面定义的变量拥有全局作用域:
<script>
var a = 10; //最外层变量
function fun() { //最外层函数
var b = 20; //内层变量
function f() { //内存函数
console.log(b); //10
}
f()
}
console.log(a); // 20
fun() //
console.log(b); //b is not defined
f() //f is not defined
</script>
- 所有window对象的属性拥有全局作用域
var a=1;
console.log(window.a)
三.函数作用域(局部作用域)
- 函数作用域是指在函数内部声明的变量和函数,只能在这个函数内部访问,否则会报错
function to(){
var a=1;
}
console.log(a) //a is not defined
//a是在函数内部声明的变量,不能在这个函数外访问
四.块级作用域
- ES6中新增的作用域,使用关键字
let或const定义块级作用域的变量,所声明的变量在指定块的作用域外无法被访问,块作用域用{}包括 let声明的语法与var声明的语法一致,基本可以用let来代替var,let允许声明一个作用域被限制在块级中的变量、语句或者表达式
let的特点:
1.只作用于块级作用域
2.不存在变量提升
let与var的区别,var存在变量提升,但是let不存在变量提升
3.不允许重复声明
let不允许在相同的作用域内重复声明同一个变量。
{
var a=10;
let a=5;//报错 Identifier 'a' has already been declared
}
{
let b=10;
let b=5; //报错 Identifier 'b' has already been declared
}
{
const c=10;
let c=5; //报错 Identifier 'c' has already been declared
}
{
function f1(foo){
let foo; //报错 同时也不能在函数内部重新声明参数
}
}
4.暂时性死区
只要用let声明的变量,那么这个变量就绑定这个块级作用域,不再受外部的影响
const
- const声明一个只读常量,一旦声明,常量的值就不能被改变。\
- const的与let的特点基本相同,同样不存在变量提升,存在暂时性死区,只能在声明后使用。
五.作用域的上下级关系
- 你的函数写在哪个作用域就是谁的子作用域
- 作用域的上下级关系是为了确定变量的使用范围
六.作用域链
只有函数可以制造作用域结构,那么只要是代码,就至少有一个作用域即全局作用域。凡是代码中有函数,那么这个函数就构成另一个作用域。如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域。
将这样的所有的作用域列出来,可以有一个结构:函数内指向函数外的链式结构。就称作作用域链。
function f1(){
function f2(){
}
}
var num = 456;
function f3(){
function f4(){
}
}