首頁 >web前端 >js教程 >JavaScript給input的value賦值引發的關於基本型別值與引用型別值問題_javascript技巧

JavaScript給input的value賦值引發的關於基本型別值與引用型別值問題_javascript技巧

WBOY
WBOY原創
2016-05-16 15:27:321236瀏覽

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

   

  

  現在我需要從另一個地方將資料傳給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  

切记:最好还是按正常来写,避免混淆

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn