Js中的資料型別 包裝物件 垃圾回收 按值傳遞
1. Js中的資料型別
Js中的資料型別分為兩類:原始型別(primitive type)和物件型別(object type)
1.1. 原始型別
JavaScript中的原始型別包括數字(Number)、字串(String)、布林值(Boolean)、undefined、null
1.1.1. 數字
當一個數字直接出現在Js程式中,我們稱之為數字直接量
i. 整型直接量:十進制整數、十六進制值、Es標準不支持八進制直接量(Es6嚴格模式禁止八進制直接量)
ii. 浮點型直接量:實數寫法(整數部分和小數點和小數部分)、指數計數法
Js數字具有足夠的精度,并可以極其近似于0.1,但是不能精確表示類似0.1這樣簡單的數字,這會帶來一些問題
var a=0.3-0.2;//0.1的近似值
var b=0.2-0.1;//0.1的另外一個近似值
a==b;//false
1.1.2. 字串
Js通過字串來表示文本,字串直接量是由單引號或雙引號括起來的字符序列,由單引號定界的字串中可以包含雙引號,由雙引號定界的字串中也可以包含單引號,
1.1.3. 布林值
指代真或假、開或關、是或否,只有兩個值,保留字:true和false,任意Js的值都可以轉換為布林值,下面這些值會轉換為false
undefined
null
0
-0
NaN
"" //空字串
所有其他值,包括物件(陣列)都會轉換成true
1.1.4. null
null是Js的關鍵字,表示一個特殊值,常用來描述空值
1.1.5. undefined
undefined表示值的空缺,是變數的一種取值,表示變數沒有初始化,如果查詢物件屬性或者陣列元素的值不存在回傳undefined說明這個屬性和值不存在,如果函式沒有回傳值則回傳undefined.undefined是預定義的全域變數,并不是關鍵字,null和undefined都不包含任何屬性和方法,所以使用 **. **和[]來存取這兩個值的成員或方法都會發生一個型別錯誤
包裝物件
看下面這段代碼:
var s="hello";
var l=s.length;
console.log(l)//5
在呼叫length的時候, JS引擎會先對原始型別資料進行包裝 new String("hello")
然后對其方法進行呼叫 new String("hello").length
字串既然不是物件,為什么會有屬性,只要參考了字串s的屬性,Js會將字串值通過呼叫new String(s)的方式轉換成物件,這個物件繼承了字串的方法,并被用來處理屬性的參考,一旦屬性參考結束,這個新創建的物件就會銷毀,
var s="test";//創建一個字串
s.len=4;//臨時創建字串物件,給屬性賦值,隨即銷毀物件
console.log(s.len)//undfined 新創建一個臨時物件,讀取len屬性
在讀取字串、數字或布林值的屬性時,創建的臨時物件稱做包裝物件,可通過String(),Number(),或Boolean()顯式創建包裝物件
1.2. 物件型別
除了原始型別外的就是物件型別了,物件(object)是屬性(property)的集合,特殊物件舉例:全域物件(global object)、陣列(array)、函式,
1.2.1. 垃圾回收
JavaScript解釋器有自己的記憶體管理機制,可以自動對記憶體進行垃圾處理(garbage collection),當不再有任何參考指向一個物件,解釋器就知道這個物件沒用了,然后自動回收它所占用的資源,
2. 不可變的原始值和可變的物件參考
2.1. 原始型別和參考型別值的比較
Js中的原始值與物件(參考型別)有著根本區別:原始值是不可更改的,任何方法都無法更改
| 資料型別 | 資料特點 |
|---|---|
| 原始值 | 原始值的比較是值的比較,只有值相等才相等 |
| 物件(參考型別) | 兩個物件有相同的屬性以及相同的屬性值也不相等,只有參考的是同一個物件才相等 |
2.2. 按值傳遞
訪問一個變數,有按值傳遞和按參考傳遞
2.1.1. 原始型別按值傳遞
i. EMCAJavaScrip里面所有函式的引數傳遞都是按值傳遞
var a=5;
fun add(a){
a+=3;
}
add(a);
console.log(a) //5
呼叫函式時,傳給形參的a,是var宣告的變數a復制出來的一個副本,
修改這個副本不影響原變數(這里宣告的變數a是原始型別中的數字型別)
ii.變數間賦值
var a=5;
var b=a;
b+=1;
console.log(b) //6
console.log(a) //5

2.1.2. 參考型別按值傳遞
var student=new Object()
function add(obj){
obj.name="Lily";
}
add(student);
console.log(student.name) //Lily
繼續:
var b=student;
b.age=10;
student.sex="女"
console.log(student.age,b.sex) //10 "女"
呼叫add函式,student的地址值復制出完全相同的一份副本作為傳入形參,這個地址指向student物件,obj空間所存的地址和student就都指向了共同的存盤空間,修改任意一個的屬性值,副本也隨之改變

再來看一段代碼
var student= new Object()
function add(obj){
obj.name = "Lily"
obj = new Object()
obj.name = "Tom"
return obj;
}
var newStudent=add(student)
console.log(student.name) //Lily
console.log(newStudent.name) //Tom

總結
兩個變數間賦值時,以及作為變數給函式傳參時,只是將原變數中的值復制一個副本給對方變數或形參變數
i. 對于原始型別的值,修改新變數,不影響原變數
ii. 對于參考型別的值的值,因為傳參和賦值時,復制的是地址值的一個副本,新變數和舊變數指向了同一個地址,修改新的變數中的屬性,原變數也隨之變動
參考:
大神的文章:https://blog.csdn.net/weixin_39728230/article/details/80607294
犀牛書
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/68844.html
標籤:其他
