DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> JavaScript入門知識 >> 關於JavaScript >> JavaScript給input的value賦值引發的關於基本類型值和引用類型值問題
JavaScript給input的value賦值引發的關於基本類型值和引用類型值問題
編輯:關於JavaScript     

 在自己做東西時,遇見了一個問題。就拿博客園的首頁右邊的搜索舉例吧,用控制台操作。

   

  

  現在我需要從另外一個地方將數據傳給input,讓其在一刷新的時候就顯示數據。

  這不難啊,於是我按照我的理解做了

  代碼如下:

  

  此時,id為zzk_q的值應該為  測試  ,即input框內應該顯示 測試 。但結果。。

  

  咦,為什麼沒有變呢,不對啊,又來來回回變著法子試一下,還是不行,當然代碼基本還是那樣子的。突然想起我以前遇見過這樣子的問題,仔細回想當時解決的方法(看樣子當時沒理解透,只是找到方法就過去了),想起來了,我試一下,代碼如下:

  看結果:

 

  這次成了。第一次遇見這個問題時沒有細想,成功了就跳過了。但這次我開始想為什麼呢?為什麼呢?怎麼會這樣啊,沒辦法理解啊。然後我自己在哪裡來回折騰,但還是想不明白。同樣是賦值這倆者有什麼差別嗎?差別在哪裡啊?後來才知道是值類型和引用類型,當然是別人給我指出來的(……)。

  然後我就去找這方面的東西看,發現這東西我看過,汗。

  自1997年Javascript被標准化以來,它定義了六種基本類型。直到ES6,JS程序中任何一個值都屬於以下幾種類型之一。

 •Undefined
 •Null
 •Boolean
 •Number
 •String
 •Object

  不過,ES6又加了一個基本類型:Symbol 類型。這個沒多大了解,不作討論,等以後熟悉再說吧,又要學。

  在JavaScript的變量中,有倆種類型的值:基本類型和引用類型的值。基本類型值(也有人稱為值類型)是簡單地數據段,它是按值訪問的,並對其中的值進行操作。而引用類型值值那些有可能有多個值構成的對象。賦值的時候,解釋器必須確定值是基本類型還是引用類型。

  基本數據類型有:Undefined、Null、Boolean、Number、String。引用類型是保存在內存中的對象,即Object,對象是方法和屬性結合。

  1.類型值的動態屬性

  這是引用類型:

var person = new Object();   
person.name = "foo";
console.log(person.name);//foo
delete person.name;
console.log(person.name)://undefined 

  這個例子中,我們先創建了一個空對象,然後將其保存在person變量中,然後給對象添加了一個屬性name,而且給這個屬性賦值了一個字符串“foo”,然後輸出,可以看到輸出了字符串foo,然後我們將這個屬性刪除,輸出undefined。這些說明,我們可以動態的給對象添加屬性和方法,如果不銷毀對象或者刪除屬性,將會一直存在。

  這是基本類型:

var name = "foo";
name.age = 22;
console.log(name.age);//undefined

   在這個中,我們將一個字符串"foo",保存在一個name變量中,然後也給它添加了一個屬性age,並賦值22,然後輸出,像我以前想的那麼該輸出22,但實際情況是undefined。

  這個是否可以理解為基本類型的值是不可變的,而引用類型是可以動態改變的。

  2.復制變量值

  和上面說的一樣,基本類型是按值訪問的。而引用類型呢,在JavaScript和其它語言不同,允許直接訪問內存中的位置,也就是說我們不可以直接操作對象的內存空間,那怎麼辦呢?在操作對象時,實際上是對操作對象的引用,引用類型的值是按引用對象訪問的。引用類型的存儲需要內存的棧內存和堆內存共同完成,棧內存保存變量標識符和指向堆內存中該對象的指針,也可以說是該對象在堆內存的地址。

  先看例子:

var num1 =5;
var num2 =num1;//5
num1+=1; //6
num2;//5 

 從一個變量向另一個變量復制基本類型的值,我們會在變量對象上重新創建一個新值,然後把該值復制到新變量分配的位置上。這倆個值是完全對立的,對倆個變量進行其他操作是互不影響的。它們應該是保存在棧內存中,如下圖所示:

 

  看一下引用類型: 

var obj1 = new Object();
var obj2 = obj1;
obj1.name = "foo";
console.log(obj2.name);  //foo
obj2.age = 22;
console.log(obj1.age);  //22 

  當從一個變量想另一個變量復制引用類型的的值時,也會將該值復制一份放到新的空間中。但是就跟上面說的一樣,引用類型的存儲要棧內存和堆內存一起完成,這個值實際上是一個指針,而這個指針指向存儲在堆中的一個對象。復制操作結束後,倆個變量實際上是同一個指針,也就是引用同一個對象。所以,改變其中的一個變量,另一個變量也會隨之改變。如下圖:


參看 JavaScript高級程序設計。

  這樣一梳理,就對一開始的問題有些明白了,開頭那個錯誤,一開始,取到input的value(此時為空),復制給title,然後以改變title期望改變input的value。但input的value(可以看成一個變量)就是一個基本類型,復制後,它倆完全獨立了,互不影響。再說成功的,將value拿出來,先將input(對象)復制給title,然後給title添加value屬性,並賦值,此時倆個指向同一個對象,改變一個,也會影響另外一個。恩,就這樣子。

  雖然很多知識從書上或其他地方看了一遍或多遍,但是等你真正遇到時感覺好奇怪。怎麼會這樣,然後自己去找答案。等找到或是別人指出後,才發現這個以前看見過,有些甚至自己解決過(不能說解決,只能說沒有深究,沒有徹底弄懂)。還有一些大學的基礎都忘的七七八八了(本來就學的不好)。連棧內存和堆內存都去搜了一下。恩,既然決定走這條路了,就好好學習吧。 

  最後:

Good good coding,day day up!

PS:(集合和引用類型、基本數據類型賦值不一樣)一個簡單的java問題 先後的賦值問題

<span style="white-space:pre">  </span>List<person> list = new ArrayList<person>(); 
<span style="white-space:pre">  </span>person pp = new person(); 
<span style="white-space:pre">  </span>list.add(pp); 
<span style="white-space:pre">  </span>pp.setIvalue(12); 
<span style="white-space:pre">  </span>pp.setIvalue(20); 
<span style="white-space:pre">  </span>pp = null;; 
<span style="white-space:pre">  </span>int b = 0; 
<span style="white-space:pre">  </span>int a = b; 
<span style="white-space:pre">  </span>b = 8; 
<span style="white-space:pre">  </span>System.out.println(a); 
<span style="white-space:pre">  </span>for (person ppp : list) { 
<span style="white-space:pre">   </span>ppp.getIvalue(); 
<span style="white-space:pre">  </span>} 
<span style="white-space:pre"> </span> 

list裡面的對象加進去就改不了,但是可以修改對象裡面的屬性值。

簡單string裡面的值就改變不了

結果:

11 
8888  

切記:最好還是按正常來寫,避免混淆

XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved