javascript范围链和执行环境的详细说明
前言:这是作者自己研究后的理解和整理,如果有错误或问题,请改正,我会继续更新!在Javascript中,范围、范围链、执行环境、执行环境堆栈的概念非常重要。我经常把它搞混。
局部函数域函数的局部区域是全局作用域窗口;
作用域链在声明函数时取决于函数的位置。在分析标识符时,它首先查找当前范围,然后查找全局顺序。调用函数在哪里并不重要。
执行环境是函数可以访问的数据和变量的集合,也就是函数作用域的链上的所有数据和变量。
执行环境是按照叠层访问的形式按照执行环境的代码执行顺序栈,然后跑出去了;如果当前执行环境(在当前作用域链存储数据和变量)找到变量,从中不难发现,之前不要去搜索它的执行环境不同的是,这个作用域链;
这是一个对象,它取决于谁执行,谁执行的是谁;(这个概念不是很清楚,在这里写一个小虎标万金油,两天后修订)
行动范围
Javascript没有概念的块级的范围,只有函数级范围:变量是在宣告自己的函数体和它们的子功能可见。
范围是变量和函数的访问范围,它控制变量和函数的可见性和生命周期。在Javascript中,变量的范围具有全局作用域和局部作用域。
当变量不在函数中声明或声明时,它不将瓦尔河视为全局变量并具有全局范围。
函数test1(){
a = 1;全局变量,仅在当前函数中有效
}
test1();
console.log(一); / / 1注意测试功能必须运行,否则不能被发现
全局变量可以用作窗口对象的属性,它们是相同的。
var B = 1;全局变量
console.log(B =窗口。B);属性 / /真正的全局变量可以作为窗口对象,它们是相同的;
窗口对象的所有属性都有一个全局范围,可以在代码中的任何地方访问;
函数中声明的变量是只能在函数中使用的局部变量,函数的参数仍然是局部变量,但不使用变量。
var = 1;全局变量
/ / console.log(D); / / referenceerror:D是未定义的引用误差,电流范围是外层的范围,还是找不到D
功能试验(D){
Console.log(C); / / 1个全局变量,它可以访问;(当前的范围,首先看不到它,寻找外部范围,直到窗户的外层发现)。
console.log(D); / / 3参数是局部变量,只能在现有的范围
}
test2(3);
作用域链
作用域链是声明在函数的位置,当第一个解析标识符从当前作用域中找到,不能在当前范围内发现,发动机将继续在范围搜索嵌套在外层,直到你找到变量,或到达最外层的范围(即全球范围内)为止;其路线已经固定,和独立的操作功能;
var a=1;
var b=2;
var=3;
var=4;
函数内部(d){范围内链---是它的全局。
var=8;
console.log(一); / / 1找不到在目前的范围,并找到一个= 1到全球范围
console.log(B); / / 2找不到B的电流范围,并找到B = 2到全球范围
Console.log(C); / / 8的电流范围发现C = 8
console.log(D); / / 7的电流范围发现D = 7,和参数也是局部范围
/ / console.log(E); / / referenceerror:E没有定义参考错误,找不到E,其作用域链内---全球
console.log(A + B + C + D); / / 18
}
功能外(e){
var = 5;范围内()的内部(全局),因此A等于无效。
var b = 6;范围内()的内部(全局),因此A等于无效。
内(7);
}
外(999); / / 999是无效的,在里面找不到
同一名称的标识符可以在多层嵌套范围中定义,称为阴影效应,内部标识符掩盖外部标识符。
窗口。一种技术允许访问被相同名称变量掩盖的全局变量。但是如果一个非全局变量被遮挡,它就不能以任何速率访问。
创建一个'lily;
var b = 'lucy;
函数外部(){
var b = 'jesica;
var c = 'susan;
函数内部(c){
console.log(一); / /莉莉
console.log(窗口。B); / /露西
console.log(B); / /杰西卡
Console.log(C); / / Jenifer
}
内('jenifer);
}
外();
执行环境
执行上下文(执行上下文)也称为执行上下文,每个执行环境都有一个可变对象(变量对象),它存储所有可以由函数访问的变量和数据,即函数范围链上的所有数据和变量,我们的代码不访问它,它用于引擎;
该函数的执行环境被推入栈时,栈的环境执行。执行该功能后,堆栈中移除它的执行环境的变量和数据将被标记了,等待垃圾收集,然后返回控制到以前的Javascript程序的执行环境。执行由这个机构控制。
应该注意的是,如果当前的执行环境(存储当前范围链中的数据和变量)找不到变量,就找不到它,它将不会查找以前的执行环境,而与范围链不一样。
代码的执行顺序不是所有行和一行的执行,但它与函数的顺序有关。
代码进入全局执行环境,全局执行环境放入环境堆栈中。
当执行一个函数时,该函数的执行环境被推到环境堆栈的顶部,而以前的执行环境又回到了原来的环境中。
全局执行环境是第一个进入的,所以它始终处于底层,它与堆栈的概念相同;
执行该函数后,它的执行环境将从范围链的顶部移除,其数据和函数标记为清除,等待垃圾收集。
对以前的执行环境给予控制权,并继续执行。
当页面关闭时,全局执行环境将被销毁。
var a=1;
var b=2;
var=3;
var=4;
函数内部(d){范围内链---是它的全局。
var=8;
console.log(一); / / 1找不到在目前的范围,并找到一个= 1到全球范围
console.log(B); / / 2找不到B的电流范围,并找到B = 2到全球范围
Console.log(C); / / 8的电流范围发现C = 8
console.log(D); / / 7的电流范围发现D = 7,和参数也是局部范围
/ / console.log(E); / / referenceerror:E没有定义参考错误,找不到E,其作用域链内---全球
console.log(A + B + C + D); / / 18
}
功能外(e){
var = 5;范围内()的内部(全局),因此A等于无效。
var b = 6;范围内()的内部(全局),因此A等于无效。
内(7);
}
外(999); / / 999是无效的,在里面找不到
上述代码的执行顺序:
代码执行进入全局执行环境,并在全局执行环境中增加代码条目。
第二行被执行,a=1被赋值;然后第三行分配B=2,然后第四行分配C=3,然后第五行分配D=4;
执行第二十行,调用外部(999)函数,然后输入外部(999)函数执行环境,声明升级,并将参数999传递给参数E。现在,环境堆栈中有两个执行环境,外部(999)是当前执行环境。
执行第十六行,赋值a=5,然后第十七行分配B=6;
要执行第十八行,调用内部(7)函数,然后输入内部(7)函数执行环境,声明升级,并将参数7传递给参数d;
执行第七行,赋值C=8,然后计算和输出;
代码优化
由于在范围链中发现变量消耗了性能,所以我们应该尽可能快地找到变量。因此,当函数嵌套时,我们应该尽可能地使用函数内部的局部变量。
我们使用函数内部的全局变量,这可以看作是一个跨域操作。如果在函数中多次使用交叉域的值,我们将其存储在本地变量中,这样我们就可以提高性能。
以上是本文的全部内容,希望能对您有所帮助,希望大家多多支持。