手机版

javascript中范围的深入分析(推荐)

时间:2021-09-08 来源:互联网 编辑:宝哥软件园 浏览:

所谓范围,可以简单理解为可以读写的范围(区域)。一些有js经验的同学可能会说:‘js没有块级作用域’,js除了全局作用域之外,只有创建作用域的功能。作用域的一个优点是它们可以隔离变量。

我们用一些例子来帮助我们理解js的范围。

警报(a);var a=1;对范围一无所知的同学可能会说alert为1或者报错;但实际上是未定义的;

现在,让我们先来谈谈js在逐行解析代码之前所做的一些准备。

Js会在逐行阅读代码之前做一些“预解析”工作,会提前发现一些“小事情”。当然,js解析器不会随便找一些数据,而是会根据var、函数、参数来找。

”js解析器是“懒惰”的,它会在正式运行代码之前将var声明的变量赋值为undefined,即var a=undefined;整个函数将被视为一个代码块,不管有多少代码。参数将在后面的示例中介绍。

当所有准备工作完成后,JS解析器开始一行行地执行代码。现在通过分析第一个例子,我们可以很容易地理解为什么它是未定义的。

让我们看看下面的例子

警报(a);var a=1;警报(a);var a=2;警报(a);让我们稍微分析一下

首先,“预解析”:解析器将寻找var

A=未定义;读第二行时;

当我读到第四行时,我还有一个=undefined;

逐行正式执行代码:

第一行alert :未定义

第二行a=1;

第三行是alert:1

第五行警报器:2

然后看看下面的例子

警报(a);var a=1;警报(a);函数a(){ alert(2);} alert(a);var a=3;警报(a);函数a(){ alert(4);} alert(a);我们还是来分析一下

首先,“预解析”:解析器会找到varfunction

A=未定义;读第二行时;

读取第四行时,a=函数a(){ alert(2);}//所有功能都是代码正式运行前的整个功能块;如果一个变量同名,则只剩下一个变量;如果变量和函数同名,则只剩下函数。

读取第六行时,a=函数a(){ alert(2);}

读取第八行时,a=函数a(){ alert(4);}

逐行正式执行代码:

第一行是alert:函数a(){ alert(4);}

第二行a=1;//表达式可以修改预解析值!

第三行是alert:1

第四行的函数不调用,跳过;

第五行alert:1;

第六行a=3;

第七行alert:3

第八行的函数不调用,跳过;

第九行alert:3

如图所示:

继续看这个例子:

var a=1;函数fn1(){ alert(a);//未定义的var a=2;} fn1();警报(a);//1首先,“预解析”:解析器将寻找var函数

A=未定义;读第一行时;

读取第二行时,fn1=函数fn1(){ alert(2);var a=2;}

逐行执行代码:的第一行a=1;

进入函数范围的第六行函数调用仍然是先在函数范围内进行预解析,然后逐行执行

函数中的预分析:a=未定义;

执行:alert:undefined

a=2;//此时,a只是函数范围内的,不会影响全局范围内的a

函数执行后,返回全局范围;

第七行alert:1

继续:

var a=1;函数fn1(){ alert(a);//1a=2;} fn1();警报(a);//2上面例子唯一的区别就是函数中的A没有var,只分析关键点

在函数作用域的第三行警告(a)中,由于函数中没有var a,因此“解析器”将在函数作用域的上部作用域中寻找一个(作用域的上下级关系的确定取决于函数是在哪个作用域下创建的,哪个作用域是哪个作用域的下级)。此时,函数的上层是全局范围,在全局范围内,a=1。因此此时第三行alert:1,后面第四行a=2,在函数作用域中仍然没有A,所以在上层作用域,也就是全局作用域中找到A,在全局作用域中修改A,这样就会使a=2在全局作用域中,所以第七行alert:2;

明白这一点,注意var的差异。

那就来吧:

var a=1;函数fn1(a){ alert(a);//未定义a=2;} fn1();警报(a);//1这个例子和上一个的区别是有一个额外的参数,这个参数作为局部变量,也就是在函数的预分析中会有var a=undefined,所以第三行alert:undefined,第四行a=2改为函数作用域中的A,不影响全局中的A,第七行alert:1;

然后:

var a=1;函数fn1(a){ alert(a);//1a=2;} fn1(a);警报(a);//1这个例子和上一个有些不同。在第六行,调用函数时会传入一个参数。在第六行,参数A是全局变量a=1。当函数执行时,第二行a=1,所以第三行alert:1和第七行alert:1。

注意这些例子之间的区别,不要混淆。

还有一个:

var a=1;函数en(){ var a=2;fn();}函数fn(){ alert(a);//1 } en();fn中的a不声明创建此函数的作用域中的值——是“创建”,而不是“调用”此函数的作用域。

附言:JavaScript中的范围和上下文概念

javascript中的范围和上下文是这种语言的独特之处,这部分归功于它们带来的灵活性。每个函数都有不同的变量上下文和范围。这些概念是javascript中一些强大设计模式的后盾。但是,也给开发者带来了很大的困惑。下面充分揭示了javascript中上下文和范围的差异,以及如何在各种设计模式中使用它们。

上下文与范围

首先要澄清的问题是,上下文和范围是不同的概念。多年来,我注意到很多开发人员经常混淆这两个术语,并错误地将其中一个描述为另一个。平心而论,这些术语已经变得非常混乱。

每个函数调用都有一个关联的范围和上下文。从根本上说,范围是基于功能的,上下文是基于对象的。换句话说,范围与每次调用函数时对变量的访问有关,并且每次调用都是独立的。Context永远是这个关键字的值,它是调用当前可执行代码的对象的引用。

以上是边肖介绍的javascript的范围(推荐)。希望对大家有帮助。如果你有任何问题,请给我留言,边肖会及时回复你。非常感谢您对我们网站的支持!

版权声明:javascript中范围的深入分析(推荐)是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。