日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

JavaScript中的基本数据类型与引用数据类型

發布時間:2025/3/21 javascript 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JavaScript中的基本数据类型与引用数据类型 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

JavaScript中的基本數據類型與引用數據類型

轉載自:https://www.cnblogs.com/c2016c/articles/9328725.html

1、棧(stack)和堆(heap)

stack為自動分配的內存空間,它由系統自動釋放;而heap則是動態分配的內存,大小也不一定會自動釋放

2、數據類型

JS分兩種數據類型:

  • 基本數據類型:Number、String、Boolean、Null、 Undefined、Symbol(ES6),這些類型可以直接操作保存在變量中的實際值。

  • 引用數據類型:Object(在JS中除了基本數據類型以外的都是對象,數據是對象,函數是對象,正則表達式是對象)

3、基本數據類型(存放在棧中)

基本數據類型是指存放在棧中的簡單數據段,數據大小確定,內存空間大小可以分配,它們是直接按值存放的,所以可以直接按值訪問

var a = 10; var b = a; b = 20; console.log(a); // 10值 console.log(b); // 20值

下圖演示了這種基本數據類型賦值的過程:

4、引用數據類型(存放在堆內存中的對象,每個空間大小不一樣,要根據情況進行特定的配置)

引用類型是存放在堆內存中的對象,變量其實是保存的在棧內存中的一個指針(保存的是堆內存中的引用地址),這個指針指向堆內存。

引用類型數據在棧內存中保存的實際上是對象在堆內存中的引用地址。通過這個引用地址可以快速查找到保存中堆內存中的對象

var obj1 = new Object();var obj2 = obj1;obj2.name = "我有名字了";console.log(obj1.name); // 我有名字了

說明這兩個引用數據類型指向了同一個堆內存對象。obj1賦值給obj2,實際上這個堆內存對象在棧內存的引用地址復制了一份給了obj2,但是實際上他們共同指向了同一個堆內存對象,所以修改obj2其實就是修改那個對象,所以通過obj1訪問也能訪問的到。

var a = [1,2,3,4,5]; var b = a;//傳址 ,對象中傳給變量的數據是引用類型的,會存儲在堆中; var c = a[0];//傳值,把對象中的屬性/數組中的數組項賦值給變量,這時變量C是基本數據類型,存儲在棧內存中;改變棧中的數據不會影響堆中的數據 alert(b);//1,2,3,4,5 alert(c);//1 //改變數值 b[4] = 6; c = 7; alert(a[4]);//6 alert(a[0]);//1

從上面我們可以得知,當我改變b中的數據時,a中數據也發生了變化;但是當我改變c的數據值時,a卻沒有發生改變。

這就是傳值與傳址的區別。因為a是數組,屬于引用類型,所以它賦予給b的時候傳的是棧中的地址(相當于新建了一個不同名“指針”),而不是堆內存中的對象。而c僅僅是從a堆內存中獲取的一個數據值,并保存在棧中。所以b修改的時候,會根據地址回到a堆中修改,c則直接在棧中修改,并且不能指向a堆內存中。

5、淺拷貝

前面已經提到,在定義一個對象或數組時,變量存放的往往只是一個地址。當我們使用對象拷貝時,如果屬性是對象或數組時,這時候我們傳遞的也只是一個地址。因此子對象在訪問該屬性時,會根據地址回溯到父對象指向的堆內存中,即父子對象發生了關聯,兩者的屬性值會指向同一內存空間。

var a={key1:"11111"} function Copy(p){var c ={};for (var i in p){c[i]=p[i]} return c; } a.key2 = ["小輝","小輝"] var b = Copy(a); b.key3 = "33333" alert(b.key1)//11111 alert(b.key3)//33333 alert(a.key3);//undefinedb.key2.push("大輝") alert(a.key2);//小輝,小輝,大輝

但是若是修改的屬性變為對象或數組時,那么父子對象之間就發生關聯,從上可知:

原因是key1的值屬于基本類型,所以拷貝的時候傳遞的就是該數據段;但是key2的值是堆內存中的對象,所以key2在拷貝的時候傳遞的是指向key2對象的地址,無論復制多少個key2,其值始終是指向父對象的key2對象的內存空間。

//ES6實現淺拷貝的方法 var a = {name:"暖風"} var b= Object.assign({},a); b.age = 18; console.log(a.age);//undefined ---------------------------------- //數組 var a = [1,2,3]; var b = a.slice(); b.push(4); b//1,2,3,4 a//1,2,4 ---------------------------------- var a = [1,2,3]; var b = a.concat(); b.push(4); b//1,2,3,4 a//1,2,4 ---------------------------------- var a = [1,2,3]; var b = [...a] b//1,2,3,4 a//1,2,4

6、深拷貝

或許以上并不是我們在實際編碼中想要的結果,我們不希望父子對象之間產生關聯,那么這時候可以用到深拷貝。既然屬性值類型是數組和或象時只會傳址,那么我們就用遞歸來解決這個問題,把父對象中所有屬于對象的屬性類型都遍歷賦給子對象即可。測試代碼如下:

var a={key1:"11111"} function Copy(p,c){var c =c||{};for (var i in p){if(typeof p[i]==="object"){c[i]=(p[i].constructor ===Array)?[]:{}Copy(p[i],c[i]);}else{c[i]=p[i]}} return c; } a.key2 = ["小輝","小輝"] var b = {} b = Copy(a,b); b.key2.push("大輝"); b.key2//小輝,小輝,大輝 a.key2//小輝,小輝

最后: 總結基本數據類型和引用數據類型區別

  • 聲明變量時內存分配不同
  • *原始類型:在棧中,因為占據空間是固定的,可以將他們存在較小的內存中-棧中,這樣便于迅速查詢變量的值

    *引用類型:存在堆中,棧中存儲的變量,只是用來查找堆中的引用地址。

    這是因為:引用值的大小會改變,所以不能把它放在棧中,否則會降低變量查尋的速度。相反,放在變量的棧空間中的值是該對象存儲在堆中的地址。地址的大小是固定的,所以把它存儲在棧中對變量性能無任何負面影響

  • 不同的內存分配帶來不同的訪問機制
  • 在javascript中是不允許直接訪問保存在堆內存中的對象的,所以在訪問一個對象時,首先得到的是這個對象在堆內存中的地址,然后再按照這個地址去獲得這個對象中的值,這就是傳說中的按引用訪問。

    而原始類型的值則是可以直接訪問到的。

  • 復制變量時的不同
  • 1)原始值:在將一個保存著原始值的變量復制給另一個變量時,會將原始值的副本賦值給新變量,此后這兩個變量是完全獨立的,他們只是擁有相同的value而已。

    2)引用值:在將一個保存著對象內存地址的變量復制給另一個變量時,會把這個內存地址賦值給新變量,

    也就是說這兩個變量都指向了堆內存中的同一個對象,他們中任何一個作出的改變都會反映在另一個身上。
        (這里要理解的一點就是,復制對象時并不會在堆內存中新生成一個一模一樣的對象,只是多了一個保存指向這個對象指針的變量罷了)。多了一個指針

  • 參數傳遞的不同(把實參復制給形參的過程)
    首先我們應該明確一點:ECMAScript中所有函數的參數都是按值來傳遞的。
      但是為什么涉及到原始類型與引用類型的值時仍然有區別呢?還不就是因為內存分配時的差別。
  • 1)原始值:只是把變量里的值傳遞給參數,之后參數和這個變量互不影響。

    2)引用值:對象變量它里面的值是這個對象在堆內存中的內存地址,這一點你要時刻銘記在心!

    因此它傳遞的值也就是這個內存地址,這也就是為什么函數內部對這個參數的修改會體現在外部的原因了,因為它們都指向同一個對象。

    原作者鏈接

    https://www.cnblogs.com/c2016c/articles/9328725.html

    總結

    以上是生活随笔為你收集整理的JavaScript中的基本数据类型与引用数据类型的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。