1、基本數據類型和引用數據類型
ECMAScript包括兩個不同類型的值:基本數據類型和引用數據類型。
基本數據類型指的是簡單的數據段,引用數據類型指的是有多個值構成的對象。
當我們把變量賦值給一個變量時,解析器首先要確認的就是這個值是基本類型值還是引用類型值。
2、常見的基本數據類型:
Number、String 、Boolean、Null和Undefined。基本數據類型是按值訪問的,因爲可以直接操作保存在變量中的實際值。示例:
var a = 10;
var b = a;
b = 20;
console.log(a); // 10值
上面,b獲取的是a值得一份拷貝,雖然,兩個變量的值相等,但是兩個變量保存了兩個不同的基本數據類型值。
b只是保存了a複製的一個副本。所以,b的改變,對a沒有影響。
下圖演示了這種基本數據類型賦值的過程:
3、引用類型數據:
也就是對象類型Object type,比如:Object 、Array 、Function 、Data等。
javascript的引用數據類型是保存在堆內存中的對象。
與其他語言的不同是,你不可以直接訪問堆內存空間中的位置和操作堆內存空間。只能操作對象在棧內存中的引用地址。
所以,引用類型數據在棧內存中保存的實際上是對象在堆內存中的引用地址。通過這個引用地址可以快速查找到保存中堆內存中的對象。
var obj1 = new Object();
var obj2 = obj1;
obj2.name = "我有名字了";
console.log(obj1.name); // 我有名字了
說明這兩個引用數據類型指向了同一個堆內存對象。obj1賦值給onj2,實際上這個堆內存對象在棧內存的引用地址複製了一份給了obj2,
但是實際上他們共同指向了同一個堆內存對象。實際上改變的是堆內存對象。
下面我們來演示這個引用數據類型賦值過程:
4、總結區別
a 聲明變量時不同的內存分配:
1)原始值:存儲在棧(stack)中的簡單數據段,也就是說,它們的值直接存儲在變量訪問的位置。
這是因爲這些原始類型佔據的空間是固定的,所以可將他們存儲在較小的內存區域 – 棧中。這樣存儲便於迅速查尋變量的值。
2)引用值:存儲在堆(heap)中的對象,也就是說,存儲在變量處的值是一個指針(point),指向存儲對象的內存地址。
這是因爲:引用值的大小會改變,所以不能把它放在棧中,否則會降低變量查尋的速度。相反,放在變量的棧空間中的值是該對象存儲在堆中的地址。
地址的大小是固定的,所以把它存儲在棧中對變量性能無任何負面影響。
b 不同的內存分配機制也帶來了不同的訪問機制
1)在javascript中是不允許直接訪問保存在堆內存中的對象的,所以在訪問一個對象時,
首先得到的是這個對象在堆內存中的地址,然後再按照這個地址去獲得這個對象中的值,這就是傳說中的按引用訪問。
2)而原始類型的值則是可以直接訪問到的。
c 複製變量時的不同
1)原始值:在將一個保存着原始值的變量複製給另一個變量時,會將原始值的副本賦值給新變量,此後這兩個變量是完全獨立的,他們只是擁有相同的value而已。
2)引用值:在將一個保存着對象內存地址的變量複製給另一個變量時,會把這個內存地址賦值給新變量,
也就是說這兩個變量都指向了堆內存中的同一個對象,他們中任何一個作出的改變都會反映在另一個身上。
(這裏要理解的一點就是,複製對象時並不會在堆內存中新生成一個一模一樣的對象,只是多了一個保存指向這個對象指針的變量罷了)。多了一個指針
d 參數傳遞的不同(把實參複製給形參的過程)
首先我們應該明確一點:ECMAScript中所有函數的參數都是按值來傳遞的。
但是爲什麼涉及到原始類型與引用類型的值時仍然有區別呢?還不就是因爲內存分配時的差別。
1)原始值:只是把變量裏的值傳遞給參數,之後參數和這個變量互不影響。
2)引用值:對象變量它裏面的值是這個對象在堆內存中的內存地址,這一點你要時刻銘記在心!
因此它傳遞的值也就是這個內存地址,這也就是爲什麼函數內部對這個參數的修改會體現在外部的原因了,因爲它們都指向同一個對象。
由於不是專業JS的,開始以爲就下面這些內容,完了,查看了下,相關資料,看到上面這些,上面轉載於:https://www.cnblogs.com/cxying93/p/6106469.html
後面是自己寫的一些東西
<head>
<meta charset="UTF-8">
<title>JS基本數據類型</title>
<script type="text/javascript">
<!--基本數據類型-->
var age = 20;
var money = 100.01;
var name = 'jack';
name2 = 'rose';
var result = true;
var scor = null;
console.log(typeof age,typeof money,typeof name,typeof name2);
// 字符串的拼接
var newNmae = name +'hank'+ name2;
console.log(newNmae);
// 3.// 任何和字符串加起來,都是字符串
// 從左往右執行
var str1 = 10 + 10 + 10 ; //30
var str2 = 10 + 10 + '10';//2010
var str3 = '10'+10 +'10';//101010
var str4 = '10'+ 10+10;//101010
var str5 = 10+'10'+10;//101010
var str6 = '10'+(10+10);//1020
console.log(str1,str2,str3,str4,str5,str6);
// 數組
var arr = [];
// 往數組裏面加東西,入棧
arr.push(22,-9,'hank',result,scor,['開車了','dididi']);
// 輸出數組中的內容
console.log(arr);
// 變量數組
for (var i = 0;i<arr.length;i++){
console.log(i,arr[i]);
}
// forin 取代for i不是數組元素,而是數組角標
for (var i in arr) {
console.log(arr[i])
}
// 從數組中刪除
arr.pop();
console.log(arr);
arr.pop();
console.log(arr);
// math 庫
var numbers = [10,89,-66,100,312];
// 取最大最小值
console.log(Math.max(10,89,-66,100,312));
console.log(Math.min.apply(this,numbers));
// 指定數據類型
// js中任何變量都是一個 對象
var x = new String;
</script>
</head>