前言:再次翻閱JS高程(第3版)過程當中,看到了「基本包裝類型」,趁熱留下此文,對JS的數據類型作個較爲深刻的小結(2018-10-19)。json
雖然JS與其餘強類型語言不同,聲明中無需預設數據類型,可是JS也是有數據類型區分的。函數
基本數據類型(存儲值):Undefined、Null、Boolean、Number、String引用類型(存儲地址指針):對象測試
基本包裝類型(臨時性質的引用類型):alert("hello world!".split(" ").length); //2指針
基本數據類型
基本數據類型一般經過字面量進行賦值,基本數據類型變量存儲的是具體的值:code
var strA = "stringA"; var strB = strA; alert(strB); //stringA strB = "stringB"; alert(strB); //stringB
將strA的賦值給strB,實際上只是將strA的值("stringA")賦值給變量strB。賦值完成,strA和strB並沒有任何關聯關係,此時修改strB的值,strA不會有任何的影響。對象
引用類型
引用類型存儲的值爲地址指針。解釋器會在內存堆中建立一個實際的對象,而後將該對象的地址賦值給變量。引用變量之間的賦值,其實是指針賦值:內存
var jsonA = {"val":"stringA"}; var jsonB = jsonA; alert(jsonB.val); // stringA jsonB.val = "stringB"; alert(jsonA.val); // stringB
對象jsonA建立後,它保存的並非具體的json對象,而是指向這個對象地址的指針。此時,將jsonA的值賦值給jsonB,只是將其保存的地址指針賦值給jsonB。賦值完成後,jsonA和jsonB同時指向內存中的同一個對象。當經過jsonB進行操做該對象,A也會跟着「改變」。string
基本包裝類型
基本數據類型只是一個簡單的,存儲值的變量,它不是對象,它並無任何的方法。可是咱們卻能夠把它當成對象同樣使用:it
var strA = "Hello-World!"; alert(strA.split("-").length); //2 alert(typeof strA); //string strA.color = "yellow"; alert(strA.color); //undefined var strB = new String("Hello-World!"); alert(strB.split("-").length); //2 alert(typeof strB); //object strB.color = "red"; alert(strB.color); //red var strC = strB; strC.color = "blue"; alert(strB.color); //red
緣由在於,當咱們調用「基本數據類型」變量的方法時,後臺爲咱們將變量包裝成對應類型的臨時對象,而後完成咱們的調用方法並返回,而後銷燬這個臨時對象。例子中,strA屬於基本類型對象。咱們用typeof檢測時返回了「string」。咱們卻能夠直接調用該變量的split和length方法。咱們將次變量看成對象同樣,對屬性「color」進行賦值,此時並不會報錯。可是當咱們去使用這個屬性時,卻提示了「 undefined」,這是是由於strA並無這個屬性。io
【基本數據類型】和【引用類型】做方法入參時的差別
一般,在函數調用時,若是入參爲【基本數據類型】時,函數的參數將以「值傳遞」的方式傳遞。此時修改函數內接收該值的局部變量,並不會對函數外的變量產生影響:
var strA = "out Function!"; changeStrVal(strA); alert(strA); //out Function! function changeStrVal(paraStr){ var strB = paraStr; strB = "in Function!"; }
可是,若是入參爲獨享,即【引用類型】,則函數內的局部變量和函數外的變量均指向同一塊內存地址。測試修改函數局部變量的屬性,函數外變量屬性也會隨之而變:
var objA = {"val":"out Function!"}; changeObjVal(objA); alert(objA.val); //in Function! function changeObjVal(paraObj){ var objB = paraObj; objB.val = "in Function!"; }