zoukankan      html  css  js  c++  java
  • javascript中的变量是传值还是传址的?

    这个标题念起来有点拗口,但却是理解数据结构的关键。标题中的4个术语,对应的英文分别是:shallow copy(注意,不是shadow copy)、deep copy、pass by value、pass by reference(或pass by address)。传址和传引用是一回事。

    一门编程语言的核心是数据结构,粗略来讲,可以把数据结构分成不可变类型(immutable)和可变类型(mutable)。为什么这么分呢?这涉及到内存分配问题。对于不可变类型,只要分配有限的内存空间即可,而对于不可变类型,理论上则要分配没有大小限制的空间。因此,这么分是出于合理利用系统资源的考虑。实际上,堆内存和栈内存分别用于保存不可变类型值和可变类型值。

    什么是不可变类型?就是该值一旦赋予某个变量,就只属于某个变量,不能同属于其他变量。如:

    window.onload=function()     
          {
                   
           var stringValue = "淡淡的";
           var anotherStringValue = stringValue;
           stringValue = "I have changed";
           alert(stringValue);// 输出  I have changed
           alert(anotherStringValue);// 输出 淡淡的
          

    此时,anotherStringValue中保存的值会不会也变成“I have changed”?不会。因为

    var anotherStringValue = stringValue;

    照stringValue中保存的字符串的原样,复制一个字符串(相应地,在内存中分配一块新空间),并将该字符串赋给anotherStringValue。换句话说,这两个变量虽然保存的值相同,但它们的值并不在一块内存中。因此,修改任何一个变量,都不会影响另一个变量。即

    stringValue = “I have changed”;

    只会影响stringValue的值。但是,确切来讲,stringValue = “I have changed”;并不是修改stringValue,而是创建了一个新字符串(相应地,在内存中分配一块新空间),然后让stringValue引用该字符串——更像是替换变量的值;原来的字符串呢?因为没有变量引用它,也就成为垃圾了(当然,垃圾所占用的内存会被回收)。

    由此可见,赋值操作对于不变类型而言,传递的是内存中的值本身。那么,对于可变类型呢?当然,传递的是内存中值的引用(或者说地址),而且无论传递多少次,内存中始终都只有一份原始值——毕竟可变类型大小莫测,只保存一份原始值能最大限度节省内存空间。例如:

    window.onload=function()    
          {
           var objectValue = {1:1,'s':'string','innerObject':{'innerArray' : [1,2,3]}};
           var anotherObjectValue = objectValue;
               objectValue[1] = 100;
           alert(anotherObjectValue[1]); //输出 100
              
           }

    不言自明,这里的anotherObjectValue通过赋值操作,从objectValue那里只获得了对原始对象( {1:1,’s’:’string’,'innerObject’:{’innerArray’ : [1,2,3]}})的引用,也就是该对象在内存中的地址,或者说“门牌号码”。因此,通过objectValue修改原始对象的第一个元素(objectValue[1] = 100;),结果同样会在anotherObjectValue[1]那里得到反映——因为这两个变量共享同一份原始值。

    在JavaScript中,给函数传递参数是按照上述默认约定——即对不可变类型,传值;对可变类型,传址——进行的。如:

    function example(str, obj){
    ……
    }
    example(stringValue,objectValue);

    调用example函数时,第一个参数传递的是实际的字符串值,第二参数传递的是对象的引用(内存地址)。

  • 相关阅读:
    推送(评论,点赞,关注)
    php组成数组
    week6 10 后端backend server和mongoDB通信
    week06 09 NodeJS Server as a RPCclient
    week06 08 postman 测试jsonrpc
    week06 07 创建RPC SERVER 换个镜像安装下载
    week05 06绑定滚动条 去抖动
    week05 05restful api
    week5 04 npm run build
    week5 03 continus loading news
  • 原文地址:https://www.cnblogs.com/muer/p/1715380.html
Copyright © 2011-2022 走看看