详解js函数的作用域链Scopes

在这里插入图片描述

在函数执行时,会创建一个作用域链(scope chain)。作用域链是一个数组,其中每个元素都是一个对象,包含变量以及对它的引用。作用域链的第一个元素是函数的活动对象(activation object),它包含了函数的参数、函数内部定义的变量和函数声明。作用域链的下一个元素是外部函数的活动对象。一直延续下去,直到全局变量对象(global variable object)。

函数的活动对象
函数的活动对象是指函数内部所声明的变量和参数。这些变量和参数在函数调用时被创建,执行函数时被使用,在函数执行完成后被销毁。函数的活动对象仅在函数内部有效,外部代码不能直接读取或操作这些变量和参数。

外部函数的活动对象
外部函数的活动对象(Active Object)指在外部函数执行期间被创建的对象,包括函数的局部变量、形参和静态变量等。这些对象存储在栈空间中,随着函数的执行而不断被创建和销毁。当外部函数执行完毕时,它的活动对象会被自动销毁,其中存储的数据也会被清除。在函数执行期间,这些活动对象可以被其他函数调用,也可以被返回给调用外部函数的代码,以便后续的处理。

举例子解释函数的活动对象和外部函数的活动对象

函数的活动对象指的是在调用函数时,函数内部创建的变量和函数参数所存储的内存空间,也可以说是函数内部的局部变量。这些变量只有在函数内部可见,外部程序无法直接访问或修改它们。

举个例子,假设有一个函数名为calculate,用于计算两个数相加的结果。这个函数中有两个参数a和b,以及一个内部变量c,它的作用是存储a和b相加的结果。在调用calculate函数时,函数内部会创建c这个变量,当函数执行完毕后,c这个变量就会被释放掉。这个内部变量c就是函数的活动对象。

而外部函数的活动对象指的是在函数外部定义的变量。它们可以在函数内部被引用,在调用函数时,函数可以读取或修改这些变量的值,因为它们的作用域不仅限于函数内部。

举个例子,假设有一个外部函数getTemperature,用于获取当前温度。这个函数中定义了一个变量temperature,用于存储当前的温度值。在调用getTemperature函数时,函数会读取这个变量的值,并返回给调用者。这个变量temperature就是函数外部的活动对象。

外部函数的活动对象的作用

外部函数的活动对象在函数调用时被创建,用于存储该函数内部的变量、参数、以及内部函数的引用。由于外部函数的活动对象位于作用域链的上层,内部函数可以通过作用域链访问到外部函数的活动对象,从而可以访问到外部函数的变量、参数等内容。这种特性被称为“闭包”,可以实现一些高级的编程技巧,例如函数柯里化、模块化等。

当函数执行时,它首先搜索自己的活动对象以查找变量,如果没找到就去搜索外部函数的活动对象。一直延伸搜索下去,直到找到全局变量对象为止。如果在所有作用域链中都没有找到变量,就会抛出一个ReferenceError异常。

作用域链是一种动态的数据结构,因为在函数执行时它是动态创建的,当函数执行完毕后,作用域链也会被销毁。这是一个重要的概念,因为它说明同一个函数在不同的执行上下文中,它的作用域链可能会不同,从而导致变量的解析结果也可能不同。

在函数内部声明的变量和函数都是局部的,只能在函数内访问。在函数外部定义的变量和函数都是全局的,可以被任何函数访问。如果在函数内部和外部同时定义了同名的变量或函数,函数内部的变量或函数会覆盖外部的。

猜你喜欢

转载自blog.csdn.net/weixin_43706224/article/details/129945217