JS作用域

作者: Welkin_qing | 来源:发表于2018-06-11 21:44 被阅读25次

一、js作用域概念---预解析规则,表达式

域:指的是一个空间、范围、区域

作用:通常指读和写

所以

作用域:指的是在一个范围内进行读或写的操作

浏览器中对js代码进行操作的是js解析器

js解析器的作用是:

1.“找一些东西”(var关键字、函数、参数)

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

在上面的代码中,

a=未定义;

即:所有变量在正式运行之前都被赋了一个值:未定义

fn1 = function fn1(){
alert(2);
}

即:所有的函数在正式运行代码之前都是整个函数块

注意:在js预解析中,遇到重名变量和函数时,只留函数。

2.逐行解读代码

通过表达式解读代码( = + * / % ++ -- ! Number() 参数)
解析代码的过程是从仓库里找东西

注意:表达式可以修改预解析内的值

二、全局与局部作用域解析以及作用域链

域的形成在js当中有两种

1.<script></script>

当中含有全局变量、全局函数(window)
读取的方式是自上而下

2.函数(作用域链)

读取的方式是由里到外
在js高程中有介绍道:作用域链的用途,是保证对执行环境有权访问的所有变量和函数的有序访问(其实和我总结的一样啦~~)
下面我们来看一个代码:

例1

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  //typeof(a) 为number
a();  //报错

解析:
第一步“找” 首先解析器先找关键字找到var a=未定义,然后又找到函数a=function a(){alert(2);},则覆盖原来的a=未定义;然后又找到a =未定义;无法覆盖,继续往下,找到a=function a(){alert(4)};现在在仓库里存入a=function a(){alert(4)};

第二步“读”从上往下看,读到alert(a),从仓库里找到刚才存入的a=function a(){alert(4)},所以输出;然后再往下第二行看见’=‘,则覆盖原来的函数,修改了原来仓库里的值使a=1;所以下一步输出a=1;再往下,函数中没有关键字,不修改仓库里的值,继续往下输出a=1;同理看见=;修改为a=3,然后输出。一直到最后a的值也是3。
但是当调用a();这个函数时,会报错,因为在仓库里a是一个变量不是一个函数。

再举一个例子:

例2

var a=1;
function fn1(){
  alert(a);   //a=未定义
  var a=2;
}
fn1();
alert(a);  //a=1

解析:
1.存入仓库里的是

a=未定义

fn1()=function fn1(){

alert(a);
var a=2;
}

自上而下往下读时,第一行有=;所以a=1;第二行函数不管,一直到调用fn1时,进入函数内部;

注意1:函数内部也是类似于作用域,分为两步;找东西和逐行读代码

进入函数内部之后,找到var a=.. ,所以函数内部仓库a=未定义;现在开始读代码,alert输出a=未定义;再往下,遇到=,给a赋值a=2;跳出函数继续往下,alert(a);

注意2:函数内部的为局部变量,现在浏览器访问到全局的仓库里找到a=1,所以输出a=1;

*局部作用域可以访问全局

同理,我再将上边的代码修改一下(将函数内部的var删除):

例3

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

解析:与原来不同的是,函数内部仓库里找不到a存的值,或者换句话说,没有存入a,则需要从外部调取,所以a=1;同时函数内部修改了a的值,改为a=2;值得一提的是,此时修改的是全部变量的值,所以当函数调用完之后输出的是a=2

例4

var a=1;
function fn1(a){
  alert(a);  //a=未定义
  a=2;
}
fn1();
alert(a);   //a=1

解析:第一步,a存入仓库:a=未定义,然后开始读代码,读取第一行使a=1;再读入函数调用,调用函数时发现函数调用使用了参数,参数a=var a...将其存入函数内部仓库,所以函数内部输出alert(a)时,a=未定义,下一步修改函数内部a=2,跳出函数;alerta(a)时,调用的是全局变量所以输出a=1;

三、调用函数局部是数据,全局声明以及for嵌套中i的取值

例5

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

解析:第一步,a存入仓库:a=未定义,然后开始读代码,读取第一行使a=1;再读入函数调用,调用函数时发现函数调用使用了参数,参数a = var a = 1;因为fn1(a)中的a来自全局,所以当读取函数内部的alert(a)时a=1;下一步修改函数内部a=2,跳出函数;alerta(a)时,调用的是全局变量所以输出a=1;

我们需要始终记住作用域的特点:先解析再执行

当然,如果我们想获取函数内部的值,就是获取局部变量的值
可以通过下面两个办法:

1.利用全局变量赋值获取

例6

var str ='';
function a(){
  a='999';
  str =a ;
}
alert(str);

2.通过函数调用

例7

function fn2(){
  var a ='999';
  fn3();
}
fn2();
function fn3(d){
  alert(d);
}

例8

alert( fn1 );       

var a = 1;
function fn1(){
    alert(123);
}

if( true ){
    
}

firefox不能对下面的函数进行预解析

对于for或者if嵌套,在js高程里称作“没有块级的作用域”,上面解释道:以for语句为例,由for创建的变量i即使在for循环执行结束后,也会依旧存在于循环外部的执行环境中。

例8

for(var i=0;i<10;i++){
  dosomething();
}
alert(i)  //i=10

相关文章

  • 变量作用域

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

  • JS作用域的练习

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

  • 你不知道的JS-上卷

    作用域整体理解:JS作用域分为函数作用域,全局作用域,with和try catch形成的块级作用域。 JS引擎在编...

  • js 闭包

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

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

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

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

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

  • JavaScript作用域的理解

    作用域:就是起作用的区域。JS的作用域规定了变量和函数可访问的范围。JS作用域分为:全局作用域和局部作用域 全局作...

  • JS 作用域链、导入导出

    1. JS 的作用域链 作用域在 JS 中表示变量的可访问性和可见性。JS 作用域有 3 种:1. 全局作用域;2...

  • JS的作用域

    JS的作用域: 全局作用域、函数作用域、eval 作用域、块级作用域 全局作用域: 函数作用域: 结果截屏: 说...

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

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

网友评论

    本文标题:JS作用域

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