JavaScript理解作用域

JavaScript作用域及作用域链

这篇文章主要谈谈我自己对作用域以及作用域链的一些理解


什么是作用域和作用域链?

作用域就是变量与函数的可访问范围,即作用域控制着变量与函数的可见性和生命周期。在JavaScript中,变量的作用域有全局作用域和局部作用域两种,局部作用域又称为函数作用域。

为了方便理解我们先看一个例子来解释作用域的范围

	console.log(scope);         //undefined
   var scope=0;
   function fun(num1,num2){
     
   	console.log(scope)       //undefined
     var scope=num1+num2
     console.log(scope)      //300
   }
  fun(100,200)
  console.log(scope)        // 0

第一个 console.log 打印结果为 undefined 原因是我们向上(JavaScript是由上而下执行的)在全局作用域中并没有找到关于 scope 的变量 , 然后第二个 console.log 打印的结果也是 undefined 的原因是此时我们的作用环境改为了局部作用域 而我们向上在函数内也没有找到关于 scope 的变量 , 然后我们可以看到在函数体的第二行我们定义了 scope 并且让他等于我们给到的两个实参相加之和 , 所以第三个 console.log 打印出了结果 300 , 函数执行完成后 我们的环境又换成了全局作用域 因为我们在第二行定义了 scope = 0 ,所以最后一个 console .log 打印了 0

这里我们看几个常见的作用域

全局作用域:

  • 程序最外层定义的函数或者变量
  • 所有末定义直接赋值的变量(包括你在函数内直接赋值的变量)
  • 所有window对象的属性和方法

函数作用域(局部作用域):

  • 局部作用域在函数内创建,在函数内可访问,函数外不可访问。

作用域链:

作用域链就是变量对象的数组!其中第一个元素是当前函数的活动对象,第二个是当前活动函数的父元素上下文的活动对象,第三个更上一级的上下文活动对象,最后一个就是全局环境的活动对象
[[Scope]]就是函数被声明时的上下文的作用域链

注意不要把执行上下文和作用域弄混淆

  1. 执行上下文可以理解为函数执行的环境,每一个函数执行时,都会给对应的函数创建这样一个执行环境。他是在函数执行之前产生的
  2. 作用域是静态的, 只要函数定义好了就一直存在, 且不会再变化
  3. 执行上下文是动态的, 调用函数时创建, 函数调用结束时就会自动释放

下面我们看一个图来理解这块内容

function f1(){
     
			function f2 (){
     
				function f3 (){
     
				}
				f3();
			}
			f2();
		}		
		f1();

JavaScript理解作用域_第1张图片
在函数定义的时候我们的作用域链就已经产生了 我们会发现在 f1定义时他的作用域链仅仅指向了全局作用域,以此类推下面的函数在定义时都会多一项指向他父元素的作用域链但他在执行时的第一项就是当前函数的活动对象这个我们前面也说过了 在右上角也可以看到我们执行上下文时进行的堆栈处理因为自身永远是最先调用完成的所以总在最上面而全局作用域总在最下面

作用域是一套规则,那作用域链是这套规则的具体实现 或者再简单明了一点来说

var a = 100
function scope() {
     
  var b = 20
  function fn() {
     
    console.log(a + b) 
  }
}

fn 要想取得 a 的值在自己的作用域中没有就得到父辈 scope 中寻找 还没有找到就到创建 scope 的全局作用域中找 , 找到了就结束了 这个寻找的方法或链子就是作用域链。


如有错误,请指正!

你可能感兴趣的:(JavaScript,作用域,作用域链)