国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 網站 > WEB開發 > 正文

JavaScript數據操作--原始值和引用值的操作本質

2024-04-27 15:12:39
字體:
來源:轉載
供稿:網友

原始值不管是變量賦值還是函數傳遞都不會改變原值,引用值不管是變量賦值還是函數傳遞,如果新變量重新賦值,則不會影響原引用值,如新變量是直接操作,就會影響原引用值。 首先明確,值和類型是兩個不同的概念。例如,null是null類型的唯一值、undefined是undefined類型的唯一值、而true和false是boolean類型僅有的兩個值等。在任何語言中,值的操作都可以歸納為以下3個方面。

復制值:即把值賦值給新變量,或者通過變量把值賦值給另一個變量、屬性或數組元素。傳遞值:即把值作為參數傳遞給函數或方法。比較值:即把值與另一個值進行比較,看是否相等。

由于值類型數據和引用型數據的值存在形式不同,自然操作它們的方法和所產生的結果也是不同的。注意,當值為值類型數據時,我們常稱之為原始值或基本值;當值為引用型數據時,我們常稱之為引用值或復合值。

使用原始值

1.復制值 在賦值語句中,操作的過程將會產生一個實際值的副本,副本的值和實際值之間沒有任何聯系,它們獨自位于不同的棧區或者堆區。這個副本可以存儲變量、對象的屬性和數組的元素。例如:

var n = 123, a, b = [], c = {}; a = n; // 復制數字123 b[0] = n; // 復制數字123 c.x = n; // 復制數字123 (a == b[0]) && (a == c.x) && (b[0] == c.x) && alert("復制的值都是相等的"); // 檢測它們的值都是相等的

在上面示例中,分別把值123復制3份給變量a、數組b和對象c,雖然它們的值是相等的,但是它們之間是相互獨立的。

2.傳遞值 當把值傳遞給函數或方法時,傳遞的值僅是副本,而不是值本身。例如,如果在函數中修改傳遞進來的值時,結果只能夠影響這個參數值的副本,并不會影響到原來的值。

var a = 123; // 原來的值 function f(x){ x = x + x; } f(a); // 調用函數修改傳遞的值 alert(a); // 查看變量a的值是否受影響,返回值為123,說明沒有變化

3.比較值 在上面的示例中我們也可以看到,當對原始值進行比較時,進行逐字節的比較來判斷它們是否相等。比較的是值本身,而不是值所處的位置,固然比較的結果可能會相等,但只是說明它們所包含的字節信息是相同的。

使用引用值

對于引用值來說,其操作的3個層面說明如下。 1.復制值 在賦值語句中,所賦的值是對原值的引用,而不是原值副本,更不是原值本身。也就是說,進行賦值之后,變量保存的都是對原值的引用(即原值的存儲地址)。當在多個變量、數組元素或對象屬性中間復制時,它們都會與原始變量保存的引用相同。

所有引用具有相同的效力和功能,都可以執行操作,如果通過其中的一個引用編輯數據,這種修改將會在原值及其他相關引用中體現出來。例如:

var a = [1,2,3]; // 賦值數組引用 b = a; // 復制值 b[0] = 4; // 修改變量b中第一個元素的值 alert(a[0]); // 返回4,顯示變量a中第一個元素的值也被修改為4

但是,如果給變量b重新賦予新值,則新值不會影響原值內容。例如:

var a = [1,2,3]; // 賦值數組引用 b = a; // 復制值 b = 4; // 為變量b重寫賦值 alert(a[0]); // 變量a的內容保持不變

重復賦值實際上是覆蓋變量對原值的引用,變為另一個值的副本或對其引用。所以不會對原值產生影響,演示示意圖如圖4-2所示。 這里寫圖片描述

2.傳遞值 當使用引用將數據傳遞給函數時,傳遞給函數的也是對原值的一個引用,函數可以使用這個引用來修改原值本身,任何修改在函數外部都是可見的。例如:

var a = [1,2,3]; function f(x){ x[0] = 4; // 在函數中修改參數值 } f(a); // 傳遞引用值 alert(a[0]); // 返回4,原值發生變化

請注意,在函數內修改的是對外部對象或數組的引用,而不是對象或數組本身的值。在函數內可以使用引用來修改對象的屬性或數組的元素,但是如果在函數內部使用一個新的引用覆蓋原來的引用,那么在函數內部的修改就不會影響原引用的值,函數外部也是看不到的。

var a = [1,2,3]; function f(x){ x = 4; // 在函數中修改參數值 } f(a); // 傳遞引用值 alert(a[0]); // 返回1,原值不會發生變化

3.比較值 當比較兩個引用值時,比較的是兩個引用地址,看它們引用的原值是否為同一個副本,而不是比較它們的原值字節是否相等。當對兩個不同值進行引用時,盡管它們具有相同的字節構成,但是這兩個引用的值卻是不相等的。

var a = new Number(1); // 引用值a var b = new Number(1); // 引用值b var c = a; // 把a的引用賦值給c alert(a==b); // 返回false alert(a==c); // 返回true

所以,{} == {},[] == [],都返回false。因為引用地址不同。

  總之,對于任何語言來說,使用值和使用引用都是數據操作的兩種基本方法。當我們操作數據時,要采用什么方法來進行處理,主要看數據的類型。值類型和引用型數據參與運算的方式不同,值類型數據通過使用值來操作數據,而引用型數據使用引用來操作數據。運算方式的不同,自然所產生的結果也不同。我們不妨再看一個示例:   

var s = "abc"; // 字符串,值類型數據 var o = new String(s); // 字符串對象,被裝箱后的字符串 function f(v){ // 運算函數 v.toString = function(){ // 修改參數的方法toString() return 123; }; } f(s); // 傳入值 alert(s); // 返回字符串"abc",說明運算沒有對原數據造成影響 f(o); // 傳入引用 alert(o); // 返回數值123,說明運算已經影響到原數據的內部結構

值類型是以實際值參與運算的,因此與原數據沒有直接聯系。而引用型以引用地址參與運算,計算的結果會影響到引用地址所關聯的堆區數據塊。但是,有一點例外,對于javaScript的字符串來說,它的操作方法就比較復雜,詳情請google!


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 克东县| 中西区| 公主岭市| 西平县| 武安市| 介休市| 阳原县| 台北市| 林甸县| 兴化市| 当雄县| 南投市| 墨江| 柯坪县| 祁门县| 扎兰屯市| 花莲县| 龙南县| 浏阳市| 保德县| 巴塘县| 平湖市| 达拉特旗| 乐山市| 南投市| 高邮市| 洞口县| 蓬莱市| 丁青县| 德令哈市| 萨迦县| 合山市| 天门市| 当涂县| 屏边| 望江县| 台州市| 将乐县| 巨野县| 台山市| 广元市|