數(shù)據(jù)類型
六種基本數(shù)據(jù)類型
- undefined
- null
- string
- number (NaN)
- boolean
- symbol
一種引用類型
- Object (包括Array和Function)
檢測方法
- typeof
用來檢測:undefined扎唾、string、number南缓、boolean胸遇、symbol、object西乖、function狐榔,無法檢測ASrray - xx instanceof type
用來檢測引用類型Array坛增、Function、Object
無法檢測基本類型
console.log(2 instanceof Number); // false
console.log(true instanceof Boolean); // false
console.log('str' instanceof String); // false
console.log([] instanceof Array); // true
console.log(function(){} instanceof Function); // true
console.log({} instanceof Object); // true
console.log(undefined instanceof Undefined);// 報錯
console.log(null instanceof Null);//報錯
- constructor
console.log((2).constructor === Number); //true
console.log((true).constructor === Boolean); //true
console.log(('str').constructor === String); //true
console.log(([]).constructor === Array); //true
console.log((function() {}).constructor === Function); //true
console.log(({}).constructor === Object); //true
如果創(chuàng)建的對象更改了圓形薄腻,無法檢測到最初的類型
function Fn(){}; //原來是方法
Fn.prototype=new Array(); //改變原型為數(shù)組
var f=new Fn();
console.log(f.constructor===Fn); // false
console.log(f.constructor===Array); // true
- 其他補充方法
- null檢測:
a === null
- Array檢測:`Array.isArray([])
- 萬金油方法
Object.prototype.toString.call()
返回[object type]
其中type是對象類型
var a = Object.prototype.toString;
console.log(a.call(2));
console.log(a.call(true));
console.log(a.call('str'));
console.log(a.call([]));
console.log(a.call(function(){}));
console.log(a.call({}));
console.log(a.call(undefined));
console.log(a.call(null));
[object Number]
[object Boolean]
[object String]
[object Undefined]
[object Null]
[object Array]
[object Function]
[object Object]
null和undefined區(qū)別
null表示"沒有對象"收捣,即該處不應(yīng)該有值。典型用法是:
- 作為函數(shù)的參數(shù)庵楷,表示該函數(shù)的參數(shù)不是對象罢艾。
- 作為對象原型鏈的終點。
undefined表示"缺少值"尽纽,就是此處應(yīng)該有一個值咐蚯,但是還沒有定義。典型用法是:
- 變量被聲明了弄贿,但沒有賦值時春锋,就等于undefined。
- 調(diào)用函數(shù)時差凹,應(yīng)該提供的參數(shù)沒有提供期奔,該參數(shù)等于undefined。
- 對象沒有賦值的屬性危尿,該屬性的值為undefined呐萌。
- 函數(shù)沒有返回值時,默認返回undefined谊娇。
堆和棧
定義
- stack棧肺孤,自動分配的內(nèi)存空間,由系統(tǒng)自動釋放
- heap堆是動態(tài)分配的內(nèi)存济欢,大小不定赠堵,不自動釋放
與數(shù)據(jù)類型的關(guān)系
- 基本數(shù)據(jù)類型存放在棧中,=:直接傳值
-
引用數(shù)據(jù)類型存放在堆中船逮,=:傳址
堆棧
深淺拷貝
數(shù)組的淺拷貝:數(shù)組里的引用類型都是淺拷貝的
/**
數(shù)組的淺拷貝
**/
//1顾腊、基本 =
var arr1 = [1, 2, 3]
var arr2 = arr1
arr1[0]=100
console.log(arr1,arr2) // [ 100, 2, 3 ] [ 100, 2, 3 ]
//2粤铭、slice
var arr3 = [1, 2, 3]
var arr4 = arr3.slice(-1) // 取數(shù)組最后一個元素
arr3[2] = 100
console.log(arr3,arr4) // [ 1, 2, 100 ] [ 3 ]
//看起來修改舊數(shù)組不改變新數(shù)組挖胃,像是深拷貝了
//但是!0鸸摺酱鸭!
var arr5 = [1, 2, 3, {b: 4}]
var arr6 = arr5.slice(-1)
arr5[3].b = 100
console.log(arr5, arr6) //[ 1, 2, 3, { b: 100 } ] [ { b: 100 } ]
// 如果數(shù)組里元素是個引用類型,那么舊數(shù)組里這個元素被改變垛吗,會影響新數(shù)組
// 所以slice()方法是淺拷貝
//3凹髓、concat 同上理
//4、遍歷
var arr7 = [1,2,3,{b:4}]
var arr8 = []
for (var i = 0; i < arr7.length; i ++) {
arr8.push(arr7[i])
}
arr7[3].b = 100
console.log(arr7, arr8) // [ 1, 2, 3, { b: 100 } ] [ 1, 2, 3, { b: 100 } ]
對象淺拷貝
// 1怯屉、 對象淺拷貝 - Object.assign
function shallowCopy4(origin) {
return Object.assign({},origin)
}
//2蔚舀、 對象淺拷貝 - 擴展運算符
// 擴展運算符(...)用于取出參數(shù)對象的所有可遍歷屬性饵沧,拷貝到當(dāng)前對象之中
function shallowCopy5(origin) {
return {
...origin
}
}
//3、使用...符
const newObje = {...obj}
//4赌躺、使用create
const newObj = Object.create({}, obj)
深拷貝
- JSON正反序列化
function deepClone1(origin) {
return JSON.parse(JSON.stringify(arr));
}
原理:利用 JSON.stringify 將js對象序列化(JSON字符串)狼牺,再使用JSON.parse來反序列化(還原)js對象
缺點:缺點就是無法拷貝 undefined、function礼患、symbol 這類特殊的屬性值是钥,拷貝完變成null
- 遞歸
function DeepClone(originObj) {
// 先判斷obj是數(shù)組還是對象
let newObj;
if(originObj instanceof Array ) {
newObj = []
} else if (originObj instanceof Object) {
newObj = {}
}
for (let key in originObj) {
// 判斷子元素類型
if (typeof(originObj[key]) === "object") {
// 如果子元素為object 遞歸一下
newObj[key] = DeepClone(originObj[key])
} else {
newObj[key] = originObj[key]
}
}
return newObj
}
- lodash的_.cloneDeep()