1.參考型別與值型別區別
-
參考型別:復雜資料型別,object(Object、Array、Date、RegRex、function)
-
值型別:基本資料型別,五種:string number boolean undefined null,
-
1.變數只能訪問堆疊中的空間
-
2.如果是參考型別(復雜資料型別),則將保存在堆中,而堆疊中存盤的是這個資料的地址,
-
3.如果是值型別(基本資料型別),則資料保存在堆疊中(資料比較小,讀取比較快捷方便)
-
4.記憶體主要有兩部分:堆疊與堆
-
<script>
/* 參考型別:array,obejct 資料存盤在堆中,地址存盤在堆疊中
值型別:string number boolean undefined null 資料存盤在堆疊中
區別:值型別:堆疊中存盤的是資料,變數賦值時拷貝的是資料,修改拷貝后的資料不會對原資料造成影響
參考型別:堆疊中存盤的是地址,變數賦值時拷貝的也是地址,修改拷貝后的資料會對原資料造成影響
*/
// 1.值型別:拷貝的是資料
var num1 = 10;
var num2 = num1; // 將num1的資料拷貝一份保存到num2中
num2 = 100;
console.log ( num1, num2 ); // 修改num2不會對num1造成影響
// 2.參考型別: 拷貝的是地址
var arr1 = [10,20,30,40,50];
var arr2 = arr1; // 將arr1的地址拷貝一份保存到num2中
arr2[0] = 100;
console.log ( arr1, arr2 ); // 修改arr2會對arr1造成影響
</script>
2.共享參考
-
JS中實際物件傳值不是真正的參考傳值(傳地址),而是傳遞參考的副本(call by sharing):按共享傳遞
-
物件賦值的本質是物件參考的副本
-
保存副本的物件如果是對物件本身進行操作:那么就是參考(操作原物件)
-
保存副本的物件如果是重新賦值:那么就重新開辟存盤空間
-
// 1.物件共享傳遞
var obj1 = { name: '我是本體' };
// 2.物件參考(共享)
var obj2 = obj1;
var obj3 = obj1;
// 3.參考的改變效果:如果操作的是物件本身(屬性或者方法)那么操作的是原物件obj1,如果把保存參考的變數賦值其他任何型別資料,那么都會重開記憶體(不影響obj1)
obj2.name = '我是新本體'; // obj2操作的是obj1本身的物件,所以修改是共用的(不開辟新空間)
console.log(obj1); // {name: "我是新本體"}
obj3 = 1; // obj3獨立開辟記憶體空間保存1,與obj1和obj2不再有關聯
console.log(obj1); // {name: "我是新本體"}
// 共享參考:共享參考是JS中復雜資料型別的本質傳遞方式而已
3.基本包裝型別
-
本身是基本資料型別,但是在執行代碼的程序中,可以呼叫相關的屬性和方法
-
JS中有三種基本包裝型別
-
Number
-
String
-
Boolean
-
/*
// 問題:為什么num是一個基本資料型別,可以像物件一樣呼叫方法呢?
// 基本資料型別
var num = 10;
console.log ( typeof num );
num.toString () ;
/*
本質相當于執行了以下代碼(JS解釋器檢測到num呼叫來toString()方法,所以快速處理了)
(1) var num = new Number(10); // 創建物件
(2) num.toString(); // 呼叫物件方法
(3) num = null; // 洗掉物件
*/
// 物件型別
var num1 = new Number(10);
/*
由于num1本身就是物件型別,所以這里可以直接呼叫,無需轉換
*/
num1.toString();
console.log ( num1 );
console.log ( typeof num1 ); // object
var str = '111';
str.toString();
/*
(1)var str = new String('111');
(2)str.toString();
(3)str = null;
*/
var bol = true;
bol.toString();
/*
(1) var bol = new Boolean(true);
(2) bol.toString();
(3) bol = null();
*/
/*
基本包裝型別和參考型別(new Number()/String()/Boolear()的區別
1.new產生的物件是長期占用記憶體,直到腳本結束
2.基本包裝型別屬于后臺瞬發,用完就銷毀了物件:物件 = null
所以:String/Number/Boolean,我們在開發中都是使用基本包裝型別
*/
4.陣列去重
陣列去重:將陣列中重復的元素去掉
-
JS陣列沒有洗掉具體元素的洗掉(只能刪掉值,刪不掉元素的索引),可以使用另外一個結構來進行存盤
-
新陣列
-
新物件
-
-
JS陣列雖然本質可以洗掉第一個和最后一個元素,可以利用這一特性,交換當前重復的元素到最后,然后進行洗掉(pop() 或者length--)
<script>
var arr = [20, 66, 88, 25, 66, 90, 88, 50]; // [20,25,66,88,90,50]
//1.排序法
// // 1.1 對陣列排序
// arr.sort(function(a,b){
// return a-b;
// });
// console.log(arr);
// // 1.2 宣告空陣列存盤去重后的陣列
// var newArr = [];
// //1.3 遍歷arr,檢查arr[i]與arr[i+1]是否相等
// for(var i = 0;i<arr.length;i++){
// if(arr[i] != arr[i+1]){
// newArr[newArr.length] = arr[i];
// };
// };
// console.log(newArr);
// 2.假設成立法
// // 2.1 宣告空陣列存盤去重后的陣列
// var newArr = [];
// // 2.2 遍歷arr,檢查arr[i]在不在newArr中
// for (var i = 0; i < arr.length; i++) {
// // 假設成立法 : 某種操作結果只有兩種清空,布爾型別存盤兩種情況,
// // 1.宣告
// var single = true; // 假設不在
// // 2.遍歷newArr檢查 只要與arr[i]相等
// for (var j = 0;j<newArr.length;j++) {
// if (arr[i] == newArr[j]) {
// single = false;
// break; // 只要發現重復元素,后面沒有必要比較
// };
// };
// // 3. 根據結果實作需求
// if (single) {
// newArr[newArr.length] = arr[i];
// };
// };
// console.log(newArr);
// 3.indexOf
// // 2.1 宣告空陣列存盤去重后的陣列
// var newArr = [];
// // 2.2 遍歷arr,檢查arr[i]在不在newArr中
// for (var i = 0; i < arr.length; i++) {
// if(newArr.indexOf(arr[i]) == -1){ // 不在
// newArr.push(arr[i]);
// }
// };
// console.log(newArr);
// 4.物件法
var arr = [20, 66, 88, 25, 66, 90, 88, 50];
/* 核心思路:利用物件的屬性名不能重復
物件的取值賦值特點
取值 : 存在,取值, 不存在,取undefined
賦值 : 存在,修改, 不存在,動態添加
1.宣告空物件 : 檢查陣列元素是否重復 (元素作為屬性名,檢查物件有沒有這個屬性)
2.宣告空陣列 :存盤去重后的陣列
3.遍歷arr,檢查arr[i]是否重復
*/
var obj = {};
var newArr = [];
for (var i = 0;i<arr.length;i++) {
// 檢查物件有沒有 arr[i] 這個屬性?
if (obj[arr[i]] == undefined) { // 未重復
newArr.push(arr[i]);
obj[arr[i]] = 1; // 這里賦值目的是為了下一次取值,不是undefined
}
};
console.log(newArr);
// 5.重復元素自我交換洗掉法
/*
核心思路:判定元素在陣列中查到的位置是否是自身(元素是一定能找到的)
* 如果是自身:說明當前元素還沒有重復
* 如果不是自身:說明當前元素在前面已經存在過:交換最后一個元素,然后把最后一個洗掉
步驟:
1.遍歷陣列的每一個元素
2.判定當前遍歷的元素在當前陣列中存在的位置,判定位置是否是當當前自己的位置
2.1.是自己位置,說明前面沒有重復,忽略
2.2.不是自己位置,說明前面已經存在:
2.2.1交換最后一個元素過來
2.2.2然后洗掉
2.2.3最后一個元素有可能已經與前面重復了,為了不跳過當前新交換的元素,重新從當前元素開始檢索
*/
arr = [1,1,2,3,5,0,1];
for (var i = 0; i < arr.length; i++) {
/ /判定當前元素在陣列中找出的位置
if (arr.indexOf(arr[i]) != i) {
// 說明不是自己:前面已經存在過
// 交換最后一個元素過來(因為最后一個可以洗掉
var temp = arr[i];
arr[i] = arr[arr.length - 1];
arr[arr.length - 1] = temp;
// 洗掉最后一個元素:兩種方式都可以
// arr.pop();
arr.length--;
// 最后一個元素有可能已經與前面重復了,所以為了保證安全,被交換過來的元素還要重新經受考驗
i--;
}
}
// 注意:以上方式會改變陣列中原來元素的順序位置
</script>
上一章:JavaScript入門第十八章(js作用域及變數預決議)
致讀者:
當你學到這里說明你的JavaScript已經入門啦 咱們的JavaScript基礎筆記在這里也要畫上一個句號了,從明天開始就會進入到我們的webapi的學習了,你準備好了嗎?
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/293629.html
標籤:其他
