zoukankan      html  css  js  c++  java
  • 作用域问题


    1.下面这段javascript代码,

    1
    2
    3
    4
    5
    6
    var msg='hello';
    for (var i=0; i<10; i++)
    {
        var msg='hello'+i*2+i;
    }
    alert(msg);

    最后一句alert的输出结果是? //hello189

    javascript只有函数域,没有块作用域的概念,所以在同一个作用域中同一个变量声明多次还是第一次声明那个!(所以for循环不会形成作用域)

    编译器在解析的时候,会发现声明了两个变量,但是后面的那个发现前面的已经声明了所以被忽略(忽略的是后面的声明,会进行重新赋值而已)。所以for循环中的msg的声明其实是无效的,从头至尾都是在操作同一个msg。

    而for循环里面的var msg='hello'+i*2+i;只是相当于再次赋值操作而已。

    var a=5;
    var b=10;
    if(a===5){
          let a=4;//the scope is inside the if-block
          var b=1;//the scope is inside the function
          console.log(a);//4
          console.log(b);//1
       }
    console.log(a);//5
    console.log(b);//1
    --------------------

    var a=5;
    function foo(){
    var a=10;
    console.log(a);
    }
    foo();//10
    console.log(a);//5

    --------------------
    var a=5;
    function foo(){
    a=10;
    console.log(a);
    }
    foo();//10
    console.log(a);//10

    if和for没有块作用域,函数有函数作用域。

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

    2.现有如下html结构

    1
    2
    3
    4
    5
    6
    <ul>
     <li>click me</li>
     <li>click me</li>
     <li>click me</li>
     <li>click me</li>
    </ul>

    运行如下代码:

    1
    2
    3
    4
    5
    6
    7
    function creatFunction () {
        var elements=document.getElementsByTagName('li');
        var length=elements.length;
        for(var i=0;i<length;i++){
            elements[i].onclick=function(){
                   alert(i);
        }
     }
    }

    依次点击4个li标签,哪一个选项是正确的运行结果()? //依次弹出4,4,4,4

    每个li标签的onclick事件执行时,本身onclick绑定的function的作用域中没有变量i,i为undefined,则解析引擎会寻找父级作用域,发现父级作用域中有i,且for循环绑定事件结束后,i已经赋值为4,所以每个li标签的onclick事件执行时,alert的都是父作用域中的i,也就是4。这是作用域的问题。

    解答:这里的事件,绑定的并非是i的值,而是i本身(alert里的i),所以当程序执行完,i的值变为4,去执行onclick事件时,执行alert(i) ,自动查找i,值为4,所以依次弹出4。

    改正:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function creatFunction (){
       var elements=document.getElementsByTagName('li');
        var length=elements.length;
        var handler = function(i){
            return fucntion(){
                alert(i);
            }
        }
        for(var i=0;i<length;i++){
            elements[i].onclick= handler(i);
     }
    }
    避免在循环中创建函数,可以在循环之外创建一个辅助函数,让这个辅助函数返回一个绑定了当前i值得函数,避免混淆
    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    3.
    if(! "a" in window){
        var a = 1;
    }
    alert(a);
    请问 a 的结果是什么? //undefined
    javascript只有函数作用域, 没有块作用域,即if,for等语句里声明的变量和其外一层的变量的作用域是一样的(函数作用域,作用域的“局部"是相对于函数而言的)。
    使用var声明的变量会被自动添加到最接近的环境的顶部(即全局作用环境中);变量提升仅提升变量声明,而不是变量赋值。
    变量提前问题,等价于:
    1
    2
    3
    4
    5
    var a;
    if(!"a"in window){
        a =1;
    }
    alert(a);

    这题还有一个细节 ,在代码的顶部var声明的变量会被认为是window的属性,如果在代码中直接使用a= 1 ,变量同样会被认为是全局变量但是并不是window的属性。
    1
    2
    3
    4
    5
    6
    7
    if(! "a"in window){
        a = 1;
    }
     
    alert(a);
    这样的话会弹出1,相当于没有了变量声明这一步,if语句就会执行。
     

  • 相关阅读:
    线段树
    数据结构<三> 队列
    数据结构<二>双向链表
    数据结构<一>单链表
    扩展欧几里德算法
    90 个 node.js 扩展模块,我们疯了
    nodejs的查询构造器
    express的路由配置优化
    express路由方案
    Redis学习笔记~目录
  • 原文地址:https://www.cnblogs.com/aixiuxiu/p/6538059.html
Copyright © 2011-2022 走看看