资讯专栏INFORMATION COLUMN

理解 js的作用域、预解析机制

galaxy_robot / 827人阅读

摘要:虽然,在我们工作中应用得越来越广泛,但是还是很多项目保留着的写法,所以,今天,带着大家重新巩固下下的作用域及预解析机制。概念作用域域,指的是一个空间范围区域,作用指的是在域内可进行读写操作。

虽然,ES6在我们工作中应用得越来越广泛,但是还是很多项目保留着ES5的写法,所以,今天,带着大家重新巩固下ES5下的作用域及预解析机制。

概念:

作用域:域,指的是一个空间、范围、区域,作用指的是在域内可进行读写操作。一个变量的作用域是程序源代码中定义的这个变量的区域。
在ES5中,只存在全局和函数级作用域,在ES6中,引入了块级作用域,js的预解析机制大概分为两个过程:预解析和自上而下逐行解读

预解析:js解析器会先把var定义的变量、function、参数等一些东西存储进仓库里面(内存)。变量var在正式运行之前,都赋值为undefined,function函数在运行之前,就是整个函数块

逐行解读

表达式=、+、-、*、/、++、--、!、%.....number()、参数都可以赋值

遇到重名的,只留下一个,变量和函数重名,函数优先级高于变量,只留下函数

函数调用(函数是一个作用域,遇到作用域都会按照先进行预解析,然后逐行解读的过程执行),先局部找参数,局部找不到就自下向上找(作用域链)

概念扯了一大段,估计初学者还是有点晕乎乎,老司机就可以提前下车了,接下来,咋们举几个小栗子,结合上面的理论,深入理解。

实践 例1:
alert(a); //error: a is not defined
a = 3;
分析:

预解析

上面说过,预解析时只会把var 、 function 、参数等存储起来,所以:
整个作用域没有找到var function 参数

逐行解读

预解析后,内存中存在a且被赋值了underfind整个变量,所有,代码执行过程中程序直接报错。

例2:
alert(a); //undefined
var a = 3;
分析:

预解析

上面说过,预解析时只会把var 、 function 、参数等存储起来,所以:
执行到第二行时,a 的值是未定义。

逐行解读

第一行:预解析后,内存中存在a且被赋值了underfined

例3:
alert(a);                    // function a (){ alert(4); }
var a = 1;
alert(a);                    // 1
function a (){ alert(2); }
alert(a);                    // 1
var a = 3;        
alert(a);                    // 3
function a (){ alert(4); }
alert(a);                    // 3
分析:

域解析

上面说过,预解析时只会把var 、 function 、参数等存储起来,所以:
执行到第二行时,a 的值是未定义。
执行到第四行时,a 的值是函数本身,也就是function a(){alert(2);}。
执行到第六行时,a 的值还是第四行时的值,也就是function a(){alert(2);},因为函数的优先级比变量高。
执行到第八行时,a 的值就变成了function a(){alert(4);} ,因为当两个函数重名时,遵循代码从上往下执行。

逐行解读

预解析完成之后,就是代码逐行执行了,
第一行:会弹出function a(){alert(4);} ,因为预解析完成之后,被存进内存的a 的值就是function a(){alert(4);}
第二行:第二行里有表达式,a 被赋了一个新的值1 表达式会改变变量的值。表达式可以改变预解析的值。
第三行:a现在被赋值为1,所有会弹出1
第四行:只是函数的声明,并没有用到表达式,而且也没有函数的调用,所以不会改变a 的值。
第五行:因为a的值没有变化,所以还是1
第六行:使用了表达式,a 被赋了一个新的值3
第七行:会弹出3
第八行:函数的声明,不会改变a 的值。
第九行:a的值没有改变,所以还是3
通过上面的栗子,相信大家应该对变量作用域的预解析过程有一定的了解了,接下来,咋们再举几个函数作用域的栗子

例4:
var a=1;
function fn1(){
    alert(a); //undefined
    var a = 2;
}
fn1();
alert(a) //1
例5:
var a=1;
function fn1(a){
    alert(a); //1
    var a = 2;
}
fn1(a);
alert(a) //1
例6:
var a=1;
function fn1(a){
    alert(a); //1
    a = 2;
}
fn1(a);
alert(a) //1
例7:
var a=1;
function fn1(){
    alert(a); //1
    a = 2;
}
fn1(a);
alert(a) //2

这几个栗子想必不用在一步步分析吧,不过就一点小改动,可能结果就截然不同,所以,大家还是需要仔细琢磨下。祝君好运。【前端交流Q群:659522518】

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/107232.html

相关文章

  • javascript引擎执行过程理解--语法分析和编译阶段

    摘要:所以觉得把这个执行的详细过程整理一下,帮助更好的理解。类似的语法报错的如下图所示三预编译阶段代码块通过语法分析阶段之后,语法都正确的下回进入预编译阶段。另开出新文章详细分析,主要介绍执行阶段中的同步任务执行和异步任务执行机制事件循环。 一、概述 js是一种非常灵活的语言,理解js引擎的执行过程对于我们学习js是非常有必要的。看了很多这方便文章,大多数是讲的是事件循环(event loo...

    molyzzx 评论0 收藏0
  • javascript系列--javascript引擎执行过程理解--语法分析和编译阶段

    摘要:所以觉得把这个执行的详细过程整理一下,帮助更好的理解。类似的语法报错的如下图所示三预编译阶段代码块通过语法分析阶段之后,语法都正确的下回进入预编译阶段。另开出新文章详细分析,主要介绍执行阶段中的同步任务执行和异步任务执行机制事件循环。 一、概述 js是一种非常灵活的语言,理解js引擎的执行过程对于我们学习js是非常有必要的。看了很多这方便文章,大多数是讲的是事件循环(event loo...

    malakashi 评论0 收藏0
  • JS解释

    摘要:预解释基础知识先介绍的基本数据类型基本数据类型值操作有引用数据类型引用地址执行环境当浏览器加载页面的时候,首先会提供一个供全局代码执行的环境全局作用域如下代码是在中好好学习天天向上把整个函数定义的部分函数本身在控制台输出 预解释 1. JS基础知识 1.1 先介绍js的基本数据类型 基本数据类型 --- 值操作 有number、string、boolean、null、undefine...

    daydream 评论0 收藏0
  • JS 作用

    摘要:首先,在创建函数时,作用域链内就会先填入对象,图片只例举了全部变量中的一部分。然后,解释器进入函数的执行环境,同样的,首先填入父级的作用域链,就是的,包括了对象活动对象。之后再把的活动对象填入到作用域链最顶部,这就是的作用域链了。 之前学习JS函数部分时,提到了作用域这一节,但是因为使用材料书不同,今天在读博客的时候发现其实还有一个知识点即作用域链,所以来写一些个人理解和认识加深记忆。...

    darry 评论0 收藏0
  • JS作用

    摘要:作用域作用读写域空间范围区域解析器全局变量全局函数。自上而下函数域局部变量局部函数。中使用,自己未定义,在中定义的变量,会报错中使用,中定义的变量,可以使用。由里而外没有块级作用域的概念,会解析里边的。并添加到当前环境中。 作用域作用:读、写域:空间、范围、区域----JS解析器----- script 全局变量、全局函数。【自上而下】函数域 局部变量、局部函数。【自里而外】 ...

    ASCH 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<