js作用域(变量提升,预解析)例题

典型例题如下:

  alert(a)   // function
  a()    //10
  var a=3;
  function a() {
    alert(10)
  }
  alert(a) //3
  a=6;
  a()  // 没有a这个函数了啊

为什么会有这样的结果呢?请看下面的例题

例题一

  /*1
  alert(a); //underfined(未定义)
  var a=1;
  */

  /*2
  alert(a)
  a=1; //报错,a is not defined
  */
  
  /*
  
  js解析器
  1.“找一些东西”(js预解析)var function 参数
   根据var找到; a=未定义,所有的变量在正式运行前都提前都赋值了未定义
   fn1=function fn1() {alert(2)}
   所有的函数,在正式运行代码之前,都是整个函数快
  2.逐行解读代码
    表达式:= + - * 、/ % ++ --! 参数 .......

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

例题二

  /*
  js预解析只会留下一个,!!!变量和函数重名了,只留下函数 
  第一步:
  a=未定义
  a=function a() {alert(2)},那么上面的那个就被干掉了;
  最后,在预解析仓库里面只有:
   a=function a() {alert(4)}
   */

  //开始逐行解读
  alert(a);//function a() {alert(4)}
  var a=1;//表达式:a就被改成1了;
  alert(a)//1
  function a() {alert(2)}//是函数声明,不是表达式,不会改变a的值
  alert(a);//1
  var a=3;
  alert(a);//3
  function a() {alert(4)};
  alert(a);//3

  a()//报错,读完代码之后,js仓库里面只有a=3;

例题三

<!--<script>-->
    <!--//1.预解析-->
    <!--//2.执行-->
<!--</script>-->

<!--<script>-->
    <!--//3.预解析-->
    <!--//4.执行-->
<!--</script>-->

 <!--
 1.
  <script>
    var a=3;
  </script>

  <script>
    alert(a);//3
  </script>
 -->

  <!--
  2. <script>
      alert(a);//报错;a is not defined
    </script>

    <script>
      var a=3;
    </script>

  -->

例题四

  var a=1;
  function fn1() {
    alert(a);//undefined
    var a=2;
  }
  fn1();
  alert(a);//1
  /*
  1.预解析
  全局的   a=未定义
  fn1=function fn1() {alert(a);var a=2;}
  2.逐行解读代码:
  表达式 a=1;
  函数调用
    1)预解析
    局部的   a =未定义

    2)逐行解读代码
    alert(a)=>未定义
          a=2;
   */

例题4-1

  var a=1;
  function fn1() {
    alert(a);//1
     a=2;
  }
  fn1();
  alert(a);//2
  /*
  1.预解析
  全局的   a=未定义
  fn1=function fn1() {alert(a); a=2;}
  2.逐行解读代码:
  表达式 a=1;
  函数调用
    1)预解析
    顺着这一层的作用域跳到上一层去找(作用域链)

    2)逐行解读代码
    alert(a)//当前作用域没有,顺着这一层的作用域跳到上一层去找(作用域链)
    a=2也是
    先弹出1,再弹出2
   */

例题4-2

  var a=1;
  function fn1(a) {//参数相当于是一个局部变量   相当于括号里面是var a;
    alert(a);//undefined
     a=2;
  }
  fn1();
  alert(a);//1
  /*
  1.预解析
     a=未定义
  fn1=function fn1(a) {alert(a); a=2;}
  2.逐行解读代码:
  表达式 a=1;
  函数调用
    1)预解析
    里面的a=未定义

    2)逐行解读代码
          里面的a=2;
   */

例题4-3

  var a=1;//标志1
  function fn1(a) {//参数相当于是一个局部变量   相当于括号里面是var a;
    alert(a);//1,这个a和标志1处的a是不相同的,这个a是局部的,外面的a是全局的
    a=2;
    alert(a)//2
  }
  fn1(a);//这个a是全局
  alert(a);//1
  /*
  1.预解析
     a=未定义
  fn1=function fn1(a) {alert(a); a=2;}
  2.逐行解读代码:
  表达式 a=1;
  函数调用
    1)预解析
    里面的a=未定义

    2)逐行解读代码
          读到fn1(a)的时候  就function fn1(var a=1)
          找到局部的a=2
   */

例题4-4

  var a=1;
  function fn1(a) {       //相当于var a;a=1(外面的)
    alert(a);//1
     var a=2;
     console.log(a);//2
  }
  fn1(a);
  alert(a);//1

例题4-5

  var a=1;
  function fn1(a) { 
    arguments[0]=3;
    alert(a);//3
    var a=2;
    console.log(a);//2
  }
  fn1(a);
  alert(a);//1

例题5 想要获取函数内的值

  //想要获取函数内的值
  // 一
  /*
  var str=''
  function fn1() {
    var a='1';
    str=a;
  }
  fn1();
  alert(str)
  */
  // 二
  function fn2() {
    var a='100元';
    fn3(a);
  }
  fn2()
  function fn3(b) {
    alert(b)
  }

例题6

  /*
  函数的大括号才是一个域
  if条件判断的大括号不是一个作用域,var 写在大括号里面和外面是一样的
   if(1){
   var a=1;
   }
   alert(a);
   for 循环的{}也不是一个块级作用域

  是作用域的标志是先解析后执行
   */


  /*
  alert(a);//undefined
  if(true){
    var a=1;
  }*/

  /*
  alert( fn1 );//underfine(最新的浏览器),ie10及以下是可以弹出函数的。。。
  if(true){
    var a=1;
    function fn1() {
      alert(123)
    }
  }*/


  /*
  //所以,以上代码要写成
  alert( fn1 );
  var a=1;
  function fn1() {
    alert(123)
  }
  if(true){

  }*/

例题7

<input type="button" value="1">
<input type="button" value="2">
<input type="button" value="3">

    /*
    //1.
    window.οnlοad=function () {
      var oBtn=document.getElementsByTagName('input');
      for(var i=0;i<oBtn.length;i++){
        oBtn[i].οnclick=function () {
          console.log(i);//3
        }
      }
    }*/

    
/*     //2
    window.οnlοad=function () {
      var oBtn=document.getElementsByTagName('input');
      for(var i=0;i<oBtn.length;i++){
        oBtn[i].οnclick=function () {
          console.log(i);//undefined     因为函数域解析了,来自下面for的var i;
          for(var i=0;i<oBtn.length;i++){
            oBtn[i].style.background='yellow'
          }
        }
      }
    } */
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值