美文网首页
js中作用域问题

js中作用域问题

作者: Hathaway_桉 | 来源:发表于2017-04-28 11:19 被阅读0次

转载地址:
http://blog.csdn.net/itzhengmaolin/article/details/54565201

作用域:在一定的范围内,对其进行读、写操作“js解析器”执行的过程至少2步:1、"找一些东西":比如 var 、function、参数2、逐行解读代码例:
alert(a);var a=1;function fn1(){ alert(2);}
解析过程:
1、JS的预解析过程 原则:遇到重名的:只留一个(变量和函数重名了,就只留下函数。无论变量在上还是函数在上,与上下是没关系的,跟有值没值有关系。因为变量=undefined,函数=整个函数块,相比之下有具体值的级别更大)
找到var关键字,然后定义其变量名等于undefined,不会管后面的值(在"JS解析器"执行的过程中,所有的变量都等于未定义) 如:a=undefined
找到function关键字,然后用其函数名等于其整个函数块。(所有的函数,在正式运行代码之前,都提前赋了一个值,这个值为整个函数块) 如:fn1=function fn1(){alert(2);}

2、逐行解读代码过程: 表达式可以修改"预解析"的值。函数的声明不属于表达式,改变不了什么东西这个过程遵循"从上往下,从左往右"的顺序执行。当执行一句完毕后,到仓库中查找是否有这个"东西"(变量、函数等)。如果有则弹出其一开始在仓库的值(使用alert方法)遇到表达式(=+ - * / % ++ -- ! 参数……等即能改变值的东西)简单来说,找var 、function、参数,并将变量赋值为undefined、函数名=整个函数,然后将他们存储在仓库中,在进行逐行解读代码的时候,在仓库中提取或修改

练习:



解析过程
1、找关键字(var、function、参数)找到37行的"var a",执行过程:a=undefined找到39行的"function a(){alert(2);}",执行过程:a=function a(){alert(2);}因为仓库里有重名的a,所以要比较优先级,值为函数的大于值为未定义,所以执行过程为a=function a(){alert(2);}找到41行的"var a ",执行过程:a=undefined因为仓库里有重名的a,所以要比较优先级,值为函数的大于值为未定义,所以执行过程为a=function a(){alert(2);}找到43行的"function (){alert(4);}",执行过程:a=function (){alert(4);}因为仓库里有重名的a,所以要比较优先级,值同为函数则比较先后,后面的覆盖前面的,所以执行过程为a=function a(){alert(4);}2、逐行解析:从上往下,从左到右依次执行代码。从36行开始,a的一开始值为function a(){alert(4);}执行37行时,修改仓库中a的值,则变为1执行39行时,并不影响a的值,所以a的值还是1后面亦是如此

一个页面两个script标签,浏览器遇到script标签会用"js解析器"来解析,只有解析完第一个script标签的内容后在执行下一个script标签内的内容,所以下面alert(a); 会报错 a is no defined。



这就是当引用别人写的jQuery库时,在对其修改
var a = 1;
function fn1()
      {
         alert(a); //undefined var a = 2;
       }
fn1();
alert(a);           

//1解析过程:
1、预解析:a=undefined;fn1=function fn1(){ alert(a); var a = 2;}
2、逐行解析;a=1遇到函数调用fn1() --函数也是一个局部的域,只要是一个域就会发生预解析和逐行解读代码。相当于其有一个小的仓库。可以理解为1个大仓库包含着1个小仓库,大仓库里的a和小仓库里的a是不同的世界,互不影响。函数调用属于表达式 函数里的预解析: a=undefined; //这里的a是局部的,外面的是全局的,两者没关系 函数里的逐行解析: 执行函数里的alert(a); 先找局部仓库里的a,所以弹出undefined 在执行函数里的var a=2; 所以局部里的a=2,并没有影响全局中的a=1 函数执行完毕后会有垃圾回收机制等
函数调用完毕后,继续全局的逐行解析

var a = 1;function fn1(){alert(a); // 1a = 2;      

//注意这里没用var声明}fn1();alert(a); // 2函数里的预解析过程为空,执行函数里的逐行解析代码:当执行到alert(a);没找到a,会顺着函数的作用域跳到上一级(从子级作用域返回到父级作用域的过程叫作用域链,由里到外找)。执行到"a=2"时,发现小仓库里没有a,则由里到外找,找到其父级有a,则修改a的值为2
所以,加var与不加var的区别体现出来了。不加var,会修改全局变量的值

var a = 1;function fn1(a){alert(a); // undefineda = 2;}fn1();alert(a); // 1

参数本质就是一个局部变量。跟上面的其中一种情况(如下)很类似函数预解析时没有发现var、function ,却发现了参数,所以a=undefined。然后逐行解读代码,当读到"alert(a);",执行结果为undefined当读到"a=2;",它会就近找小仓库里有没有a,执行结果为a=2,全局的a还是1不影响

相关文章

  • 2019-08-13JS里面的作用域Scope

    作用域指一个变量的作用范围。 JS的作用域 在JS中,有两种作用域 全局作用域直接编写在script标签中 JS代...

  • 第八节: JavaScript中this指向问题

    1. this指向问题 1.1 认识词法作用域 其实我们js中的作用域就是词法作用域,我们会发现词法作用域最重要的...

  • 第八节 JavaScript中this指向问题

    this指向问题 1.1 认识词法作用域 其实我们js中的作用域就是词法作用域,我们会发现词法作用域最重要的特征是...

  • js 闭包

    一、js 作用域 讲闭包首先就要理解 js 的作用域。再 ES5 中,js 有两种作用域,全局作用域和函数作用域(...

  • ES5中JS的作用域和变量提升(hoisting)

    ES5 中JS 的作用域: 在ES5 中,JS 只有两种形式的作用域:全局作用域和函数作用域。 全局作用域全局对象...

  • 变量作用域

    变量作用域:静态作用域、动态作用域JS变量作用域:JS使用静态作用域JS没有块级作用域(全局作用域、函数作用域等)...

  • 干货!月薪80k前端大佬面试笔记:JS闭包解析!

    三点注意事项 JS没有块级作用域,只有全局作用域和局部作用域(函数作用域)。 JS中的作用域链,内部的作用域可以访...

  • js中作用域问题

    转载地址:http://blog.csdn.net/itzhengmaolin/article/details/5...

  • JavaScript块级作用域

    块作用域{ }JS中作用域有:全局作用域、函数作用域。没有块作用域的概念。ECMAScript 6(简称ES6)中...

  • JS作用域的练习

    Js作用域练习demo1 Js作用域练习demo2 JS作用域练习demo3 JS作用域练习demo4 JS作用域...

网友评论

      本文标题:js中作用域问题

      本文链接:https://www.haomeiwen.com/subject/jdmozttx.html