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

    认识JavaScript中的变量

    JavaScript中的变量有两种类型,一种是基本类型、一种是引用类型。

    • 基本数据类型:Defined,Null,Boolean,Number,String。注意String是属于基本数据类型,这不同于其他高级语言。
    • 引用类型即对象,包括内置对象和自定义对象。

    需理解的差异

    关于复制

    对于基本类型的变量,就是我们印象中对于变量的理解。

    var a = "TabWeng";
    var b = a;
    console.log("a:"+a+", b:"+b);
    a = "Weng";
    console.log("a:"+a+", b:"+b);
    

    运行结果:

    a:TabWeng, b:TabWeng
    a:Weng, b:TabWeng
    

    我们来看另一个例子:

    var a = new Object();
    a.name = "TabWeng";
    var b = a;
    console.log("a'name:"+a.name+", b'name:"+b.name);
    a.name = "Weng";
    console.log("a'name:"+a.name+", b'name:"+b.name);
    

    运行结果:

    a'name:TabWeng, b'name:TabWeng  
    a'name:Weng, b'name:Weng
    

    这个结果就不同了,我只修改了 a.name 的值,b.name 的值也跟着发生变化,答案只能是它们的值都指向同一个地方,即它们都指向同一块内存,只要内存的值发生变化,因为另一个也指向这个内存,自然就获取了变化后的值。而对于基本类型的变量,也就是我们大家所理解的,在复制后就开辟新的内存进行数据存储,所以两个变量互不干扰。

    关于传参

    JavaScript的参数传递都是按值传递

    基本类型变量很好理解,但是对于引用类型的变量也许存在疑惑,不要紧,你只要理解下面这句话即可:
    引用类型变量的传参是按值传递,但是访问引用变量的值时依然是按引用访问同一个对象。

    下面举三个例子,对于引用类型,读者需理解透彻。
    第一个例子是基本类型变量的传参,第二、三是引用类型变量的传参:

    var name = "TabWeng";
    
    function sayFunction(name){
      name = "Hi,"+name;
      console.log(name);
    }
    
    sayFunction(name); 
    console.log(name);
    

    运行结果:

    Hi,TabWeng
    TabWeng
    
    var Person = new Object();
    Person.name = "TabWeng";
    
    function sayFunction(obj){
      obj.name = "Hi," + obj.name;
      console.log(obj.name);
    }
    
    sayFunction(Person);
    console.log(Person.name);
    

    运行结果:

    Hi,TabWeng
    Hi,TabWeng
    

    虽然是按值传递,但是在访问的时候是按引用访问同一个对象,所以Person.name也改变了。

    var Person = new Object();
    Person.name = "TabWeng";
    
    function sayFunction(obj){
      obj.name = "Hi," + obj.name;
      console.log(obj.name);
      obj = new Object();
      obj.name = "My name is Tom, I am go to another memory";
      console.log(obj.name);
    }
    
    sayFunction(Person);
    console.log(Person.name);
    

    运行结果:

    Hi,TabWeng
    My name is Tom, I am go to another memory
    Hi,TabWeng
    

    这个例子说明了不是按引用传递,否则第三行的结果应该是My name is Tom, I am go to another memory

    作用域

    作用域链

    作用域链很好理解,一句话概括变量在作用域中的访问权限:
    外面不能访问里面,里面可以访问外面,在搜索变量时,从里向外搜索。

    作用域链是在创建函数的时候产生的,在创建函数的时候,会创建它的执行环境和作用域链,一开始的时候,会创建一个包含全局环境(全局对象)的作用域链,然后把该函数的活动对象推入到作用域链的前端(也就是里面,最下面),如果函数里面还有函数,那么再依次推入,这样就形成一条作用域链。

    假设作用域链(实际上是一张列表)里面有三个指针指向三个对象,列表最上面的指针指向全局对象(假设称为obj_1),中间的指针指向活动对象(假设称为obj_2),下面的指针指向最前端的活动对象(假设称为obj_3)。那么,当前的活动对象的变量是无法访问下面指针的活动对象的,即obj_2无法访问obj_3的变量,反之就可以。

    延长作用域链

    • try catch
    • with
      以上两者可延长作用域链,把变量放在作用域前端(即当前环境)。

    没有块级作用域

    for(var i = 0; i < 3; i++){
      console.log("in i: "+i);
    }
    
    console.log("out i:"+i);
    

    运行结果:

    in i: 0  
    in i: 1  
    in i: 2  
    out i:3
    

    这与其他高级语言不同。

    参考

    • 《JavaScript高级程序设计》
  • 相关阅读:
    绕过验证码登陆的方法(适合只需登陆一次可以记住登陆台的网站)
    Throughput Controller(吞吐量控制器) 感觉就像个线程控制器来的
    时间戳 和 日期 转换的方法 (含获取当前时间戳的方法)
    pip使用笔记
    可以模拟多种浏览器的网站
    浏览器兼容性说明
    测试套件的使用
    python 时间对比大小 和 间隔多少天
    django数据库操作
    mysql连接工具记录
  • 原文地址:https://www.cnblogs.com/hlwyfeng/p/6080506.html
Copyright © 2011-2022 走看看