zoukankan      html  css  js  c++  java
  • 变量的作用域

    变量的作用域:

    作用:起作用。

    域:范围,区域。

    1,变量的生命周期。

    2,哪里可以访问变量。

    ----------------作用域-----------

    1,全局作用域  全局都可以访问的变量的区域

    2,局部作用域:主要就是函数作用,理解为:函数体内部的执行环境。

    不存在的变量或函数会报错;不存在的属性或方法,返回undefined;

    javascript 没有块级作用域:

    比如

    {   ......   }  //在这个花括号里面的变量就叫块级作用域,但JS中没有块级作用。

    比如:

    if(){......}   for(){.....)等等:

    <script>
    if (true) {
    var a=0;//属于全局变量,因为JS不存在块级作用域,即:{}花括号之间的作用域,其他语言会有
    }
    for (var i = 0; i < elements.length; i++) {
    var b=1;//属于全局变量,因为JS不存在块级作用域,即:{}花括号之间的作用域,其他语言会有
    }
    </script>

    ----------------------------------------

    <script>
    function fn(){
    var x=y=1;
    console.log(x);//返回 1
    console.log(y);//返回 1
    }
    // console.log(x);//报错,因为x是局部变量,不能再函数体以外进行访问。
    fn();//如果不执行该方法,则输出下面y就会报错: y is undefined
    console.log(y);//返回 1
    </script>

    ---------js没有块级作用,所以变量都是全局作用域------------

    script type="text/javascript">
    if (true) {
    var name="xm";  //在js中没有块级作用域,所以,这里的name是全局变量。
    };
    document.write(name);//输出:xm
    </script>

    --------------------

    script type="text/javascript">
    if (true) {
    var a.name="xm"; //这里的对象a没有声明,所以会出现uncaught SystaxError的错误。
    };
    document.write(a.name);// 虽然js不存在块级作用,但是每个对象必须声明。变量可以直接使用,如:name等于 var name。
    </script>

    -----------------

    因为不用var声明的变量是全局变量,y是全局变量,可以输出;x是局部变量,因此输出x会报错。

    <script type="text/javascript">
    function fn(){
    var x=y=1;//这里的y用var声明,所以是全局变量。
    }
    fn();
    document.write(y);
    document.write(x);
    </script>

    因为不用var声明的变量是全局变量,y是全局变量,可以输出;x是局部变量,因此输出x会报错。

    ---------------

    在JS中,主要是全局变量和,函数变量(局部变量)

    说白了,下面的两个a完全不同,第一个是全局变量,函数内的是局部变量。

    <script type="text/javascript">
    var a="xm"; //这里的a 是全局变量
    function fn(){
    var a="xh";  //这里的a 是局部变量,在函数中重新声明了。
    document.write(a); //这里读取的是局部变量,所以a="xh"。
    }
    fn();
    document.write(a); //这里读取的是全局变量,而不是局部变量,所以a="xm"。
    </script>

    -------

    下一个例子完全相反:

    -------

    说白了,下面只有一个全局变量a。

    <script type="text/javascript">
    var a="xm";
    function fn(){
    a="xh";  //在函数内没有用var声明变量,说明是全局变量,a的值被改为 "xh"。
    document.write(a); //全局变量 a="xh"。
    }
    fn();
    document.write(a);//全局变量a在函数内被修改为"xh",所以这里的a="xh"。
    </script>

     ===============

    全局作用域的  变量对象   window:

    <script>
    var a=70;
    function add(){
    return a+10;
    }
    add();//返回80;
    console.log(window.a===a);//返回 true
    console.log(window.add===add);//返回 true
    </script>

    -------------------------

    局部作用域的 变量对象 :

    <script>
    var a=70;
    function add(){
      return a+10;

      var b=10;
      function fn(){

        var c=20;
        return a+b+c+20;
      }
    }
    </script>

    解析:

    1,全局作用域变量对象

      window.a===a

      window.add===add

    2,add函数的局部作用变量对象,是看不见摸不着的,假如局部变量的变量对象是:add

      add.b===b

      add.fn===fn

    3,fn函数的局部作用变量对象,是看不见摸不着的,假如局部变量的变量对象是:fn

      fn.c===c

    三个作用域就连成了一个作用域链:

    作用域都是从内层向外层查找属性值。

    如查找 fn.c 的值的查找顺序----fn局部作用域----add局部作用域-----window全局作用域,取最近存在的值,即:fn.c=20,如果不存在,返回undefined

    如查找 fn.a 的值的查找顺序----fn局部作用域----add局部作用域-----window全局作用域,fn.a=window.a=70。

    如查找 add.a 的值的查找顺序 ---add.a局部作用域 -----window全局作用域,add.a=window.a=70

    如查找 add.c 的值的查找顺序----add.a局部作用-----window全局作用域,不存在,所以add.c 返回:undefined,这里add.c!==fn.c,只可以向外查找,不能向内查找。

    所以,局部变量一定比全局变量效率高,内层变量一定比外层变量效率高。

    ============

    通过 with(obj) 来延长作用域链,但是这个很鸡肋,降低效率,还有其他一切问题,不推荐使用,了解即可,如下代码:

    <script>
    /*
    注意比较以下全局变量对象和局部变量对象的属性和方法:

    全局变量对象window的属性及方法:
    1,window.person对象
    2,window.score属性*/
      var person={};
      var person.name="xm";
      var person.sex="male";
      var score=80;

    /*局部变量对象person
    1,person.name 等价于修改了上面的window.person.name
    2,person.sex 等价于修改了上面的window.person.sex
    3,person.score 等价于widow.score*/
    with(person){
      name="xh";//全局属性中已经定了变量对象window的属性person对象中name的属性,所以这里只是重新赋值。
      sex="female";//全局属性中已经定了变量对象window的属性person对象中sex的属性,所以这里只是重新赋值。
      score=90; //因为person不存在该属性,全局属性中已经定了person的属性,所以继承了window.score的值,并且修改了。
    }
    </script>

    ============

    <script type="text/javascript">

    //以下 person未定义的变量 报错

    document.write(person || person="xm");
    document.write(window.person || window.person="xm");
    </script>

    不存在的变量或函数会报错;不存在的属性或方法,返回undefined;||是短路操作,形如a||b,如果a的值转换成布尔值是true的话,a||b等于a;如果a的值转换成布尔值是false的话,a||b等于b。

    --------------------

    <body>
    <button>1</button>
    <button>2</button>
    <button>3</button>
    <script type="text/javascript">
    var btns=document.getElementsByTagName('button');
    for (var i = 0; i < btns.length; i++) {
    btns[i].onclick=function(){
    alert(i);
    }
    }
    </script>
    </body>

    以上是:这里是由于先绑定,后触发,给每个按钮绑定事件,但是在触发的时候i已经是循环完之后,所以i的值一直都是3。

  • 相关阅读:
    阿里巴巴研究员叔同:云原生是企业数字创新的最短路径
    【OpenYurt 深度解析】边缘网关缓存能力的优雅实现
    K8s 原生 Serverless 实践:ASK 与 Knative
    一年增加 1.2w 星,Dapr 能否引领云原生中间件的未来?
    源码解读:KubeVela 是如何将 appfile 转换为 K8s 特定资源对象的
    绘本推荐
    油猴Tampermonkey
    lan蓝tern灯
    6岁叛逆期
    留白
  • 原文地址:https://www.cnblogs.com/Knowledge-is-infinite/p/10614788.html
Copyright © 2011-2022 走看看