JS全局与局部作用域解析、作用域链(上)

讲解实例3:

<script>

alert(a);

var a = 1;

alert(a);

function a(){alert(2);}

alert(a);

var a =3;

alert(a);

function a(){alert(4);}

alert(a);

a();

</script>

结果看得出来吗?

揭晓结果,依次是:

function a(){alert(4);}

1

1

3

3

报错:a is not a function

详解:

预解析阶段:根据var function 参数……等来找东西

首先,a=undefined;

其次,a=function a(){alert(2);}; //覆盖掉前面的:a=undefined;

---注意:遇到重名的,只留下一个;变量和函数重名,就只留下函数;---

再次,a=undefined; //与函数重名,只留下一个,a依然等于function a(){alert(2);}

最后,a= function a(){alert(4);}//覆盖掉前面的:a=function a(){alert(2);} ;此时a=function a(){alert(4);}

因此,预解析完毕时:a = function a(){alert(4);}

逐行解读代码:每次读取的时候,都是先去找仓库里面的东西

第一个alert(a); 弹出:function a(){alert(4);}

下一行 var a = 1 ,这是个表达式,它能修改预解析后仓库里面的值;

因此执行var a =1之后;a= functioni a(){alert(4);} 将被修改为 a = 1

第二个alert(a); 弹出:1

再下一行 function a(){alert(2);},这是个函数声明,不是表达式;所以,它不会改变仓库里面的任何东西;(a依然等于1)

于是,继续往下读;

第三个alert(a); 弹出: 1

接下来 var a = 3又是个表达式,于是执行之后,仓库里的“a = 1” 又将会被更改为“a = 3”;

第四个alert(a); 弹出:3

接下来又遇到一个函数声明:function a(){alert(4);},函数声明不会去改变仓库里面的值,因此a 依然等于3;

第五个alert(a); 弹出:3

最后的a(); 看起来是个函数调用,但是要注意:你所看到的代码,并不是JS解析器看到的代码【此时我们的JS解析器中唯一有的东西就是 "a = 3",但是已经没有任何的函数了 】

那么这时的a(); 就相当于3(); //这个语法是ECMAscript 不支持的;这时会报错:a is not a function;

原文地址:https://www.cnblogs.com/tongguilin/p/12229885.html

时间: 2024-11-10 19:42:02

JS全局与局部作用域解析、作用域链(上)的相关文章

JS全局与局部作用域解析、作用域链(下)

作用域: 域:空间.范围.区域…… 域分为:全局 一般在script标签范围内定义的变量.函数,我们习惯性地叫做全局变量.全局函数 一个script就是一个域,只要是一个域,就会发生:预解析.逐行解读代码 页面上可以写多个script 举个栗子1: <script> alert(a); </script> <script> var a = 1; </script> JS 会一块一块进行解析.执行,是单线程的 执行第一块时,会先在那个仓库找a:找不到a,就报错

JavaScript作用域问题:预解析、全局与局部作用域解析、作用域链

要想了解JS作用域问题,就要先了解浏览器的JS解析器的工作方式,当浏览器读到script脚本代码时,JS解析器便开始工作.其工作步骤主要分为两部分: JS解析器: 1.“找一些东西”(预解析):var function 参数 例: alert(a); //undefined var a=1; alert(a); //1 function fn1(){alert(2);} JS解析器会先找到var function 参数进行预解析. 找到var定义的变量a时,解析为a = 未定义,不会读取具体值.

js的执行环境和作用域链

执行环境 js的执行环境就是:定义了变量或函数有权访问的其他数据,决定了它们各自的行为.每个环境都有一个与之相关联的对象,环境中定义的变量和函数都保存在这个对象中. 全局变量就是最外围的环境,通常被认为是window对象.全局变量和局部变量会在环境栈中,当执行环境在执行完环境中的所有代码后会销毁,环境栈会将该栈弹出,定义的变量与函数也会被销毁,而全局变量会在程序退出后销毁. 作用域链 作用域是保证对执行环境有权访问  的所有变量  的有序访问. 链的形成: 作用域链的前端是当前执行环境的变量对象

JS高级 -- 执行上下文与作用域链

这个问题涉及到三个点: 1. 执行上下文 2. 函数嵌套导致的执行上下文栈 3.闭包 1 <script> 2 var a = 1; 3 var f1 = function(){//第一个函数 4 var a = 2; 5 var b = 1; 6 7 var f2 = function(){//第二个函数 8 var c = 1; 9 var f3 = function(){//第三个函数 //第三个函数执行,他自己的执行上下文中没有a,b,c,则从父级函数f2的执行上下文中去找,f2中有c

js的变量,变量作用域,作用域链

变量声明: 使用var关键字声明,如果使用没有声明的变量,则JS会自动声明此变量根据变量作用域.如果变量只声明为赋值,则此时值是undefined.重复声明变量,在JS不会报错,会依据最后一次的声明来处理变量. 变量作用域: 一个变量的作用域是,程序代码定义这个变量的区域,全局变量在程序代码内任何地方都可以访问. 包括在{}函数,对象内的变量(属性)成为局部变量. 在函数体内定义的变量成为局部变量,作用域也是局部,函数参数也是局部变量. 他们只在函数体内有意义. 在函数体内,局部变量优先于全局变

【动画演示】:JS 作用域链不在话下

作者:Lydia Hallie译者:前端小智来源:dev 点赞再看,养成习惯 本文 GitHub https://github.com/qq44924588... 上已经收录,更多往期高赞文章的分类,也整理了很多我的文档,和教程资料.欢迎Star和完善,大家面试可以参照考点复习,希望我们一起有点东西. 本篇我们来看看啥是作用域以及作用域链,首先,来看看下面的代码: const name = "Lydia" const age = 21 const city = "San Fr

JS的作用域链与原型链

来一波,好记性不如烂笔头. 这两条链子可是很重要的. 作用域链 当执行一段JS代码(全局代码或函数)时,JS引擎会创建为其创建一个作用域又称为执行上下文(Execution Context),在页面加载后会首先创建一个全局的作用域,然后每执行一个函数,会建立一个对应的作用域,从而形成了一条作用域链.每个作用域都有一条对应的作用域链,链头是全局作用域,链尾是当前函数作用域.作用域链的作用是用于解析标识符,当函数被创建时(不是执行),会将this.arguments.命名参数和该函数中的所有局部变量

js作用域链中变量提前的问题

js訪问变量是从内到外,这条作用域链上面的每一个活动变量也是从内到外的.比方一个函数,首先由arguments和函数内部声明的变量,然后是外层的能訪问的变量.直至最后window全局对象.当出了这个函数,函数内部声明的活动对象就会销毁,所以外部滴根本无法訪问函数内部声明的对象的.之所以说js会把全部的变量提前也是针对不同的作用域的,在最外面.则是把全部的全局变量和全局的函数声明提前,在函数内部,则是先把函数内部声明的变量和函数提前

js闭包和作用域链

闭包 闭包 函数对象之间可以通过作用域链相互关联起来,函数体内部的变量都可以保存在函数作用域内 这种特性称做“闭包”. 什么是变量? 变量就是为一切事物赋的一个name; var的作用,初始化变量. 变量作用域 程序源码中定义这个变量的区域就就是变量作用域.(名字放在什么地方了) 全局变量拥有全局作用域,在js代码的任何地方都是有定义的.(这个名字很响亮) 在函数体内声明的变量在函数体内有效,他们是局部变量,函数参数也是局部变量他们只在函数体内有定义.(里层的能拿到的外层的值,外层的拿不到里层的