JavaScript的作用域

181 阅读2分钟

一.怎么是作用域

  • 作用域就是变量生效的范围
  • 作用域的用处是隔离变量,不同作用域下的同名变量不会冲突

二.全局作用域

在代码中任何地方都能访问到的对象拥有全局作用域:

  • 最外层函数 和在最外层函数外面定义的变量拥有全局作用域:
<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来代替varlet允许声明一个作用域被限制在块级中的变量、语句或者表达式

QQ图片20220530160851.png

let的特点:

1.只作用于块级作用域 QQ图片20220530155314.png

2.不存在变量提升
let与var的区别,var存在变量提升,但是let不存在变量提升 QQ图片20220530155137.png

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声明的变量,那么这个变量就绑定这个块级作用域,不再受外部的影响

QQ图片20220530160008.png

const

  • const声明一个只读常量,一旦声明,常量的值就不能被改变。\
  • const的与let的特点基本相同,同样不存在变量提升,存在暂时性死区,只能在声明后使用。

QQ图片20220530160449.png

五.作用域的上下级关系

  • 你的函数写在哪个作用域就是谁的子作用域
  • 作用域的上下级关系是为了确定变量的使用范围

六.作用域链

只有函数可以制造作用域结构,那么只要是代码,就至少有一个作用域即全局作用域。凡是代码中有函数,那么这个函数就构成另一个作用域。如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域。
将这样的所有的作用域列出来,可以有一个结构:函数内指向函数外的链式结构。就称作作用域链。

function f1(){
     function f2(){  
     }
}
var num = 456;
function f3(){
     function f4(){  
     }
}

QQ图片20220530164915.png