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>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM