zoukankan      html  css  js  c++  java
  • js中对象引用出现的问题

    先看一个特别不符合直觉的代码

    1         <script type="text/javascript">
    2             var a = [1,2,3,4];
    3             var b = [1,2,3,4];
    4             console.log(a==b); //出现false,按照常规理解,a和b应该是一样的,都是[1,2,3,4],同时也说明,js中不能这么判断数组时候相同
    5         </script>

    再看代码

            <script type="text/javascript">            
                var a = 3;
                var b = 3;
                console.log(a==b); //true
            </script>

    第二段代码为true很好理解,都是3,那第一段代码为何为false,都是[1,2,3,4]呀

    ----------

    在js中,基本类型的变量(有数字,字符串,布尔值)赋值的时候,就是值复制过去,以后相互之间就没有关系了。

    比如说:

            <script type="text/javascript">
                var a = 5;
                var b = a; //a是基本类型数据,赋值给b,那么在内存中,b就存了a的值5,以后各走各的路,a,b没有关系了。
                b += 5;
                console.log(a,b); // 5,10
            </script>
     1         <script type="text/javascript">
     2             var a = [1,2,3,4];
     3             var b = a;
     4             var c = [1,2,3,4];
     5             console.log(a==b); //true;
     6             console.log(a==c); //false;
     7             
     8             //b是a赋值过去的,现在更改b的内容,再看看a
     9             b.push(5);
    10             console.log(a); // [1, 2, 3, 4, 5 ] 很奇怪吧,a也变了啊,这里对a没有操作呀???
    11         </script>

    上面的代码,a不是基本类型,是个数组对象,赋给b的时候,改动b也改动了a,真是奇怪。这就是在js中,当a不是基本类型数据时,内存中a存的是一个内存地址,a赋值给b时候,ab共同指向一个内存地址,改动了a,也就改动了b,改动了b,也就改动了a,如下

     1         <script type="text/javascript">
     2             var a = [1,2,3,4];
     3             var b = a;
     4             var c = [1,2,3,4];
     5             console.log(a==b); //true;
     6             console.log(a==c); //false;
     7             
     8             //b是a赋值过去的,现在更改b的内容,再看看a
     9             b.push(5);
    10             a.push(6);
    11             console.log(a); // [1, 2, 3, 4, 5 ,6 ] 很奇怪吧,a也变了啊,这里对a没有操作呀???
    12             console.log(b); // [1, 2, 3, 4, 5 ,6 ]
    13             console.log(a==b); //true;
    14         </script>

    再看一段代码

     1         <script type="text/javascript">
     2             var a = [1,2,3,4];
     3             var b = a;
     4             
     5             //b是a赋值过去的,现在更改b的内容,再看看a
     6             b = [1,2,3,4,5]; //这里不用b.push(5);看看什么变化
     7             console.log(a); // [1, 2, 3, 4 ] a不变
     8             console.log(b); // [1, 2, 3, 4, 5 ]
     9             console.log(a==b); //false;
    10         </script>

    是不是很困惑,不是说了改动b,a也跟着动吗?

    第6行代码,不是b对象改动,而是又重新赋值一个对象给了b,b是数组对象的另一个对象实例(只要程序中出现赋值,那就是重新生成),他俩也就没关系了,如果用b的某个方法,改动的b的值,那a和b仍然指向同一个地址!

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

    所有的一切,总结出来一句话:

    在js中,基本类型数据,在内存中存的就是个数据

    a | 5

    b | 5

    a,b值相同,就是a==b

    但是对象不一样

    在内存中,对象存的是个地址,a和b这两个对象相同的话,需要值和地址都相同才可以。

    a | 内存指针1

    b | 内存指针1

    这样ab才相同。

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

    在面向对象程序中,如果用这种方式创建对象,如下

     1         <script type="text/javascript">
     2             function CreatePerson(name){
     3                 this.name = name;
     4                 this.test = function(){
     5                     console.log(this.name);
     6                 }
     7             }
     8             
     9             var my_obj1 = new CreatePerson('张三');
    10             var my_obj2 = new CreatePerson('李四');
    11             
    12             alert(my_obj1.test == my_obj2.test); //false
    13             
    14             //虽然代码上是一样的,但是my_obj1和my_obj2是两个对象实例,他们各自在内存中开辟一个地方,放置test方法,如果对象实例很多,就比较占内存了。
    15             
    16         </script>

    所以,要更改下,用prototype,在对象中,不同的地方,如属性,写在构造函数里,相同的地方,如方法,用原型来写。如下:

     1         <script type="text/javascript">
     2             function CreatePerson(name){
     3                 this.name = name;
     4             }
     5             
     6             CreatePerson.prototype.test = function(){
     7                 console.log(this.name);
     8             }
     9             
    10             var my_obj1 = new CreatePerson('张三');
    11             var my_obj2 = new CreatePerson('李四');
    12             
    13             alert(my_obj1.test == my_obj2.test); //true
    14             my_obj1.test(); // 张三
    15             my_obj2.test(); // 李四
    16             
    17             
    18         </script>
  • 相关阅读:
    uboot向内核模块传递参数的方法
    arm下用shell控制gpio
    u-boot的内存分布和全局数据结构
    Ambarella SDK build 步骤解析
    MMU段式映射(VA -> PA)过程分析
    ambarella H2 添加文件到ext4文件系统
    使用U-Boot的TFTP(远程/网络内核)
    使用U-Boot的NFS(远程/网络用户空间)
    君正Ingenic X1000E_halley2 更改Logo
    【自动化测试】robotframework中一些建议可能需要掌握的关键字
  • 原文地址:https://www.cnblogs.com/html55/p/9765636.html
Copyright © 2011-2022 走看看